JVM出现频繁Full GC的真实案例分析

bash 复制代码
public void synchData() {

 
        List<JobOmsWarehouse> jobOmsWarehouseList = omsWarehouseMapper.getOmsWarehouseList();
        if (CollectionUtils.isEmpty(jobOmsWarehouseList)) {
            return;
        }
      dataCockpitGoodsManufacturerNotCollectedMapper.deleteGoodsManufacturerNotCollected();
        List<String> warehouseCodeList = jobOmsWarehouseList.stream().map(JobOmsWarehouse::getWarehouseCode).collect(Collectors.toList());
        WmsBaseWareHouseAndSubOwner wmsBaseWareHouseAndSubOwner = new WmsBaseWareHouseAndSubOwner();
        wmsBaseWareHouseAndSubOwner.setWarehouseCodeList(warehouseCodeList);
        List<WmsBaseWareHouseAndSubOwner> wmsBaseWareHouseAndSubOwnerList = wmsInBoundOrderTimelyMapper.selectWmsBaseWareHouseList(wmsBaseWareHouseAndSubOwner);
        if (CollectionUtils.isEmpty(wmsBaseWareHouseAndSubOwnerList)) {
            return;
        }
        GoodsManufacturerNotCollected goodsManufacturerNotCollected = new GoodsManufacturerNotCollected();
        goodsManufacturerNotCollected.setFlag("0");
        List<String> goodCodeList = omsGoodsManufacturerNotCollectedMapper.selectGoodsManufacturerNotOfGoodsCodes(goodsManufacturerNotCollected);
        for (WmsBaseWareHouseAndSubOwner wareHouseAndSubOwner : wmsBaseWareHouseAndSubOwnerList) {
            if (StringUtils.isEmpty(wareHouseAndSubOwner.getWarehouseCode())) {
                continue;
            }
            if ("prod".equals(profilesActive)) {
                wmsBaseWareHouseAndSubOwner.setDatabaseName("jp_wms" + wareHouseAndSubOwner.getWarehouseCode().replace("W", ""));
                wmsBaseWareHouseAndSubOwner.setDatabaseName1("jp_wmsbase");
            } else {
                wmsBaseWareHouseAndSubOwner.setDatabaseName("jp_test_wms" + wareHouseAndSubOwner.getWarehouseCode().replace("W", ""));
                wmsBaseWareHouseAndSubOwner.setDatabaseName1("jp_test_wmsbase");
            }          wmsBaseWareHouseAndSubOwner.setWarehouseCode(wareHouseAndSubOwner.getWarehouseCode());
            try {
                // 判断库是否存在
                int databaseNameCount = wmsInBoundOrderTimelyMapper.selectDbExists(wmsBaseWareHouseAndSubOwner.getDatabaseName());
                if (databaseNameCount > 0) {
                    int wmsInvListCount = wmsInBoundOrderTimelyMapper.selectTablesExists(wmsBaseWareHouseAndSubOwner.getDatabaseName(), "wms_inv_list");
                    if (wmsInvListCount > 0) {
                        List<WmsBaseWareHouseAndSubOwner> subOwners = wmsInBoundOrderTimelyMapper.selectWmsMoveLibraryList2(wmsBaseWareHouseAndSubOwner);
                        if (CollectionUtils.isEmpty(subOwners)) {
                            continue;
                        }
                        for (WmsBaseWareHouseAndSubOwner subOwnerBean : subOwners) {
                            try {
                                if (StringUtils.isEmpty(subOwnerBean.getWarehouseCode())) {
                                    continue;
                                }
                                wmsBaseWareHouseAndSubOwner.setWarehouseCode(subOwnerBean.getWarehouseCode());

                                //查询只关注未采集商品库存
                                if (!CollectionUtils.isEmpty(goodCodeList)) {
                                    wmsBaseWareHouseAndSubOwner.setGoodsCodeList(goodCodeList);
                                    int pageSize = 500;
                                    Integer total = wmsGoodsManufacturerNotCollectedMapper.getGoodsManufacturerInfoCount(wmsBaseWareHouseAndSubOwner);
                                    int totalPage = (total + pageSize - 1) / pageSize;
                                    for (int i = 1; i <= totalPage; i++) {
                                        PageHelper.startPage(i, pageSize, false);
                                        List<GoodsManufacturerNotCollected> goodsManufacturerInfoList = wmsGoodsManufacturerNotCollectedMapper.getGoodsManufacturerInfoList(wmsBaseWareHouseAndSubOwner);
                                        if (CollectionUtils.isNotEmpty(goodsManufacturerInfoList)) {
                                            dataCockpitGoodsManufacturerNotCollectedMapper.insertGoodsManufacturerNotCollected(goodsManufacturerInfoList);
                                        }
                                    }
                                }
                            } catch (Exception e) {
                                e.printStackTrace();
                                XxlJobHelper.log("查询报错=" + wmsBaseWareHouseAndSubOwner.getDatabaseName(), e);
                            }
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
                XxlJobHelper.log("表结构不存在=" + wmsBaseWareHouseAndSubOwner.getDatabaseName(), e);
            }

            //1初始、已拍照的
            GoodsManufacturerNotCollected goodsManufacturerNotCollected2 = new GoodsManufacturerNotCollected();
            goodsManufacturerNotCollected2.setFlag("1");
            goodsManufacturerNotCollected2.setWarehouseCode(wareHouseAndSubOwner.getWarehouseCode());
            int total = omsGoodsManufacturerNotCollectedMapper.selectGoodsManufacturerNotCollectedListCount(goodsManufacturerNotCollected2);
            int pageSize = 500;
            int totalPage = (total + pageSize - 1) / pageSize;
            for (int i = 1; i <= totalPage; i++) {
                PageHelper.startPage(i, pageSize, false);
                List<GoodsManufacturerNotCollected> notCollecteds = omsGoodsManufacturerNotCollectedMapper.selectGoodsManufacturerNotCollectedList(goodsManufacturerNotCollected2);
                if (CollectionUtils.isNotEmpty(notCollecteds)) {
                    dataCockpitGoodsManufacturerNotCollectedMapper.insertGoodsManufacturerNotCollected(notCollecteds);
                }
            }
        }
    }

该Java函数synchronousBadProductData()的主要功能如下:

同步仓库数据:从OMS系统获取仓库列表,并删除数据驾驶舱中的相关指标数据。

获取WMS仓库信息:根据OMS仓库列表,获取对应的WMS仓库信息。

处理每个WMS仓库:

检查数据库和表是否存在。

查询并插入未采集的商品库存信息到数据驾驶舱。

处理已拍照商品:对于特定状态(如初始或已拍照)的商品,分页查询并插入到数据驾驶舱。
为什么总是出现java.lang.reflect.InvocationTargetException at sun.reflect.GeneratedMethodAccessor948.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at com.xxl.job.core.handler.impl.MethodJobHandler.execute(MethodJobHandler.java:31) at com.xxl.job.core.thread.JobThread.run(JobThread.java:163) Caused by: java.lang.OutOfMemoryError: GC overhead limit exceeded
出现 java.lang.reflect.InvocationTargetException 和

java.lang.OutOfMemoryError: GC overhead limit exceeded 的原因及解决方法如下:

bash 复制代码
原因分析
内存溢出:
OutOfMemoryError: GC overhead limit exceeded 表示垃圾回收(GC)过于频繁,导致性能下降。这通常是由于内存泄漏或对象占用过多内存导致的。
反射调用异常:
InvocationTargetException 表示通过反射调用的方法抛出了异常。这里可能是被调用的方法内部出现了异常。
bash 复制代码
解决方法
1. 增加JVM堆内存
在启动应用时增加JVM参数来增加堆内存大小。

-Xms1024m -Xmx1024m

bash 复制代码
2. 优化代码减少内存消耗
检查是否有大量对象创建后没有及时释放。
使用 try-with-resources 语句确保资源正确关闭。
减少不必要的对象创建,特别是大对象。
3. 分页处理大数据量
如果处理的数据量很大,可以考虑分批处理,避免一次性加载过多数据。
bash 复制代码
 int pageSize = 500;
  Integer total = wmsGoodsManufacturerNotCollectedMapper.getGoodsManufacturerInfoCount(wmsBaseWareHouseAndSubOwner);
  int totalPage = (total + pageSize - 1) / pageSize;
  for (int i = 1; i <= totalPage; i++) {
      PageHelper.startPage(i, pageSize, false);
      List<GoodsManufacturerNotCollected> goodsManufacturerInfoList = wmsGoodsManufacturerNotCollectedMapper.getGoodsManufacturerInfoList(wmsBaseWareHouseAndSubOwner);
      if (CollectionUtils.isNotEmpty(goodsManufacturerInfoList)) {
          dataCockpitGoodsManufacturerNotCollectedMapper.insertGoodsManufacturerNotCollected(goodsManufacturerInfoList);
      }
  }
bash 复制代码
4. 检查反射调用的方法
确保被反射调用的方法内部没有异常。
添加异常捕获和日志记录,以便追踪具体问题。
bash 复制代码
 try {
      // 调用方法
  } catch (Exception e) {
      e.printStackTrace();
      XxlJobHelper.log("方法调用异常:" + e.getMessage(), e);
  }
bash 复制代码
5. 监控和调整GC策略
使用工具(如 VisualVM 或 JConsole)监控应用的内存使用情况。
调整GC策略,例如使用 -XX:+UseG1GC 来启用 G1 垃圾收集器。
通过以上步骤,可以有效解决内存溢出和反射调用异常的问题。
相关推荐
程序喵大人1 分钟前
写C++十年,我现在怎么设计类和模块?(附真实项目结构)
开发语言·c++·类和模板
工业互联网专业7 分钟前
基于Spark的新冠肺炎疫情实时监控系统_django+spider
python·spark·django·vue·毕业设计·源码·课程设计
Yh87020312 分钟前
2025年经济学专业女生必考证书指南:打造差异化竞争力
python
黄焖鸡能干四碗18 分钟前
信息系统安全保护措施文件方案
大数据·开发语言·人工智能·web安全·制造
BYSJMG20 分钟前
大数据毕业设计推荐:基于Spark的零售时尚精品店销售数据分析系统【Hadoop+python+spark】
大数据·hadoop·python·spark·django·课程设计
醉方休1 小时前
python 自动化在web领域应用
python
liulilittle1 小时前
Unix/Linux 平台通过 IP 地址获取接口名的 C++ 实现
linux·开发语言·c++·tcp/ip·unix·编程语言
Source.Liu1 小时前
【Python基础】 18 Rust 与 Python print 函数完整对比笔记
笔记·python·rust
Nerd Nirvana1 小时前
C++编程——异步处理、事件驱动编程和策略模式
开发语言·c++·策略模式·嵌入式开发·事件驱动·异步处理
大模型真好玩1 小时前
大模型工程面试经典(五)—大模型专业领域微调数据集如何构建?
人工智能·python·面试