# 数据量大导致的问题

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;

在这里插入图片描述

插入总计时间

。。。未完待续

以上是关于# 数据量大导致的问题的主要内容,如果未能解决你的问题,请参考以下文章

DataTable 数据量大时,导致内存溢出的解决方案

导出数据量大的报表内存溢出怎么办?

程序循环特别慢数据量大怎么办

ABAP中,用Ranges定义的内表,由于数据量大导致运行错误

Oracle 数据库 - 使用UEStudio修改dmp文件版本号,解决imp命令恢复的数据库与dmp本地文件版本号不匹配导致的导入失败问题,“ORACLE error 12547”问题处理(代码片段

MySQL删除千万级数据量导致的慢查询优化