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 垃圾收集器。
通过以上步骤,可以有效解决内存溢出和反射调用异常的问题。
相关推荐
不去幼儿园29 分钟前
【MARL】深入理解多智能体近端策略优化(MAPPO)算法与调参
人工智能·python·算法·机器学习·强化学习
Ajiang28247353041 小时前
对于C++中stack和queue的认识以及priority_queue的模拟实现
开发语言·c++
幽兰的天空2 小时前
Python 中的模式匹配:深入了解 match 语句
开发语言·python
Theodore_10225 小时前
4 设计模式原则之接口隔离原则
java·开发语言·设计模式·java-ee·接口隔离原则·javaee
网易独家音乐人Mike Zhou5 小时前
【卡尔曼滤波】数据预测Prediction观测器的理论推导及应用 C语言、Python实现(Kalman Filter)
c语言·python·单片机·物联网·算法·嵌入式·iot
安静读书5 小时前
Python解析视频FPS(帧率)、分辨率信息
python·opencv·音视频
----云烟----6 小时前
QT中QString类的各种使用
开发语言·qt
lsx2024067 小时前
SQL SELECT 语句:基础与进阶应用
开发语言
小二·7 小时前
java基础面试题笔记(基础篇)
java·笔记·python
开心工作室_kaic7 小时前
ssm161基于web的资源共享平台的共享与开发+jsp(论文+源码)_kaic
java·开发语言·前端