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 垃圾收集器。
通过以上步骤,可以有效解决内存溢出和反射调用异常的问题。
相关推荐
Dontla几秒前
vscode怎么设置anaconda python解释器(anaconda解释器、vscode解释器)
ide·vscode·python
waicsdn_haha10 分钟前
Java/JDK下载、安装及环境配置超详细教程【Windows10、macOS和Linux图文详解】
java·运维·服务器·开发语言·windows·后端·jdk
_WndProc12 分钟前
C++ 日志输出
开发语言·c++·算法
qq_4335545421 分钟前
C++ 面向对象编程:+号运算符重载,左移运算符重载
开发语言·c++
qq_5290252939 分钟前
Torch.gather
python·深度学习·机器学习
数据小爬虫@40 分钟前
如何高效利用Python爬虫按关键字搜索苏宁商品
开发语言·爬虫·python
ZJ_.42 分钟前
WPSJS:让 WPS 办公与 JavaScript 完美联动
开发语言·前端·javascript·vscode·ecmascript·wps
Narutolxy1 小时前
深入探讨 Go 中的高级表单验证与翻译:Gin 与 Validator 的实践之道20241223
开发语言·golang·gin
Hello.Reader1 小时前
全面解析 Golang Gin 框架
开发语言·golang·gin
禁默1 小时前
深入浅出:AWT的基本组件及其应用
java·开发语言·界面编程