背景
测试环境有个old generation 非常占用内存.所以需要排查
过程
问题出现
同事压测的时候,发现old generation 占用内存非常大
例子是下图的样子:
相关配置:
- jdk 11
- 最大堆内存2g
- gc算法用默认的
g1
排查问题
dump 文件
使用jamp
命令将java的内存dump出来
jmap -dump:format=b,,live,file=<file-path> <pid>
mat工具分析
然后去下载mat工具下载地址
安装之后打开,点击Dominator Tree
:
就可以看到对象以及大小
可以看到有一个900m大小的HashSet
, 这是一个去重的set , 每次都会往这里塞入设备id ,当循环结束,会自动不会再被引用,然后会被gc回收.
结论
这不是内存泄漏,而是一个有1kw 数据的的大set ,也就是一个大对象
我们找运维调大了最大的堆内存,问题解决
后续优化: 后续我们打算不使用HashSet 塞字符串去重,而是用布隆过滤器去重