# 数据量大导致的问题
Posted MarlonBrando1998
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了# 数据量大导致的问题相关的知识,希望对你有一定的参考价值。
java.lang.OutOfMemoryError: GC overhead limit exceeded
- 错误描述:被占用的内存,经过多次长时间的
GC
操作都无法回收,导致可用内存越来越少,俗称内存泄露 - 问题代码实例:具有 6000000数据的
list
集合,短时间内没有释放内存,导致Gc
回收频繁
@Override
public void insertDatas() {
List<DataDto> list = new ArrayList<>();
for (int i = 0; i < 60000000; i++) {
String uuid = String.valueOf(UUID.randomUUID());
String code = "code" + i;
String name = "name" + i;
DataDto dataDto = new DataDto();
dataDto.setId(uuid);
dataDto.setDataCode(code);
dataDto.setDataName(name);
dataDto.setDataLocation("/" + uuid +"/"+code);
dataDto.setRecordtime(new Date());
dataDto.setType(String.valueOf(i));
list.add(dataDto);
}
dataDtoMapper.insertBatch(list);
}
问题排查
- 增大堆内存
-Xms1024m -Xmx4096m
- 设置老年代 的内存
-XX:+UseG1GC -XX:G1HeapRegionSize=n -XX:MaxGCPauseMillis=m
-XX:ParallelGCThreads=n -XX:ConcGCThreads=n
- 获取heap内存快照,使用工具,找出内存泄露发生的原因并进行修复。
- 优化代码以使用更少的内存或重用对象,而不是创建新的对象,从而减少垃圾收集器运行的次数。如果代码中创建了许多临时对象(例如在循环中),应该尝试重用它们。
最终解决方案
- 修改代码
@Override
@Transactional(rollbackFor = Throwable.class)
public void insertDatas() {
List<DataDto> list = new ArrayList<>();
for (int i = 0; i < 6000000; i++) {
String uuid = String.valueOf(UUIDUtils.simpleUuid());
String code = "code" + i;
String name = "name" + i;
DataDto dataDto = new DataDto();
dataDto.setId(uuid);
dataDto.setDataCode(code);
dataDto.setDataName(name);
dataDto.setDataLocation("/" + uuid + "/" + code);
dataDto.setRecordtime(new Date());
dataDto.setType(String.valueOf(i));
dataDto.setDescribe(String.valueOf(i));
list.add(dataDto);
if (list.size() == 20000) {
logger.info("list 对象满 20000");
for (List<DataDto> dataDtos : Lists.partition(list, 1000)) {
dataDtoMapper.insertBatch(dataDtos);
}
list.clear();
}
}
if (CollectionUtils.isNotEmpty(list)) {
dataDtoMapper.insertBatch(list);
}
}
批量插入速度慢问题
- 问题原因:大数据量(插入5000000),表中建有多个索引
解决方案
- 修改数据库可执行
Sql
的大小,mysql
默认为1m
show variables like '%max_allowed_packet%';
SET GLOBAL max_allowed_packet=268435456;
插入总计时间
。。。未完待续
以上是关于# 数据量大导致的问题的主要内容,如果未能解决你的问题,请参考以下文章
ABAP中,用Ranges定义的内表,由于数据量大导致运行错误
Oracle 数据库 - 使用UEStudio修改dmp文件版本号,解决imp命令恢复的数据库与dmp本地文件版本号不匹配导致的导入失败问题,“ORACLE error 12547”问题处理(代码片段