使用mat 分析java OOM问题

1.使用MAT打开oom-facilityservice.hprof文件

2.生成 内存泄漏报告

3.查看泄露详情

4.分析报告

5.通过报告可以看出有一个List大小为2个G,并且

复制代码
 at com.huawei.drms.facilitymgmtservice.domain.odn.service.impl.OdnRelationDomainServiceImpl.queryUpByDevice(Ljava/util/List;Ljava/util/List;)Ljava/util/List; (OdnRelationDomainServiceImpl.java:102
在这个地方
6.分析代码
1.先分析
queryUpByDevice方法
可以看出这个查询入参为deviceIds和sources,一次查询应该不可能查出2个G的内容
service

在调用

复制代码
queryUpByDevice,向list<OdnRelationPo> 中添加数据,这是就可以确定,八成是递归方法没有推出导致的。
java 复制代码
 private void odnQueryUp(List<OdnPointPo> pointPos, String deviceId) {
        String currentDeviceId = deviceId;
        while (true) {
            List<String> source = Arrays.asList(OdnRelationSourceEnum.UP.getCode(),
                OdnRelationSourceEnum.FULL.getCode());
            List<OdnRelationPo> odnRelPos = odnRelationDomainService.queryUpByDevice(
                Collections.singletonList(currentDeviceId), source);

            if (CollectionUtils.isEmpty(odnRelPos)) {
                break;
            }
            OdnRelationPo odnRelPo = odnRelPos.get(0);
            if (StringUtils.isNotEmpty(odnRelPo.getADeviceId())) {
                pointPos.add(0, new OdnPointPo(odnRelPo, "A"));
                currentDeviceId = odnRelPo.getADeviceId();
            } else {
                break;
            }
        }
    }

修改后

java 复制代码
 private void odnQueryUp(List<OdnPointPo> pointPos, String deviceId) {
        // 死循环现在最大查询20次
        int limit = 20;
        List<String> usedDeviceIds = new ArrayList<>();

        String currentDeviceId = deviceId;
        List<String> source = Arrays.asList(
            OdnRelationSourceEnum.UP.getCode(),
            OdnRelationSourceEnum.FULL.getCode()
        );
        List<OdnRelationPo> odnRelPos;
        while (limit > 0) {
            if (usedDeviceIds.contains(currentDeviceId)) {
                // 已经查询过了,代表当前路径是个环,退出
                break;
            }
            usedDeviceIds.add(currentDeviceId);

            odnRelPos = odnRelationDomainService.queryUpByDevice(
                Collections.singletonList(currentDeviceId), source);
            if (CollectionUtils.isEmpty(odnRelPos)) {
                // 数据为空,退出
                break;
            }

            OdnRelationPo odnRelPo = odnRelPos.get(0);
            if (StringUtils.isNotEmpty(odnRelPo.getADeviceId())
                && !currentDeviceId.equals(odnRelPo.getADeviceId())) {
                // 更换查询条件
                pointPos.add(0, new OdnPointPo(odnRelPo, "A"));
                currentDeviceId = odnRelPo.getADeviceId();
            } else {
                break;
            }

            limit--;
        }
    }
相关推荐
Han_han919几秒前
递归相关题目:
java
yong99906 分钟前
基于Qt的文件传输系统
开发语言·qt
yuan199976 分钟前
基于 MATLAB PSO 工具箱的函数寻优算法
开发语言·算法·matlab
kTR2hD1qb15 分钟前
Claude Code Skill的介绍与使用
java·前端·数据库·人工智能
汤米粥25 分钟前
python学习——核心语法三
java·python·学习
basketball61634 分钟前
Kadane算法 C++实现
java·c++·算法
handler0135 分钟前
【C++】二叉搜索树详解及其模拟实现(代码)
开发语言·c++·算法·c··二叉搜索树·搜索树
luj_176837 分钟前
残熵算法的稳健防灾逻辑
c语言·开发语言·c++·经验分享·算法
better_liang1 小时前
每日Java面试场景题知识点之-如何设计分布式锁
java·redis·zookeeper·面试·分布式锁
战族狼魂1 小时前
集 “自动飞行、智能识别、实时预警、勤务联动” 于一体的高速公路应急车道无人机检测系统方案
java·人工智能·大模型·无人机