同事排查oom问题,并且告诉了我方法,纪录一下,一个很方便的插件。
前提是保存了堆快照,如果没有那就猜去吧。
- 使用jhat命令
jhat XX.hprof
浏览器打开localhost:7000
最下方可以看到,常用的功能
最常用的应该是查看堆统计信息,点击跳转到localhost:7000/histo/
这里排查的话建议先根据报名查询一下自己的项目的类的实例,看下最多的占用多少,如果数量和空间很大,那么多半就是它导致的,如果发现占用很少,那就麻烦了,可能哪里有一个集合,存了太多字符串或者数字或者类型的实例导致的,也可能是哪个依赖存在内存泄漏。
这里可以点进去,比如最大的那个class[C char数组,对应的当然是字符串,进去以后可以看下是不是很多大对象,我这个没有太多大的。
如果存在异常的大的,可以点进去看看引用它的地方,如果是字符串,就可以看到字符串内容:
如果到了这里没有思路。
- 内存分析工具MemoryAnalyzer
点击上面可以下载,也可以下载eclipse然后安装插件,之前我就是这样的,但是后来同时发我了独立版,方便很多,毕竟开发是用idea
打开并加载堆快照文件
直接可以看到堆概况
同时,它还会自动分析泄漏原因,像我这个自动就把泄漏原因找到了,是因为日志打印过于频繁导致的
One instance of "ch.qos.logback.classic.AsyncAppender" loaded by "org.springframework.boot.loader.LaunchedURLClassLoader @ 0xe001a7c0" occupies 345,241,648 (83.84%) bytes. The memory is accumulated in one instance of "java.lang.Object[]" loaded by "<system class loader>".
可以看到一个实例引用了83%的空间。
如果它自动分析的不对(实际上还是蛮对的),可以自己看
这里就相当于jhat的那个堆统计信息页面了
进来可以看到,自动根据内存占用找到引用并可以层层查看,其实大部分情况下就能找到原因了。