文章目录
内存泄漏
发现问题
top
VisualVM
下载地址:https://visualvm.github.io/
Arthas
官网:https://arthas.aliyun.com/
原因分析
代码层面
这里列举两种常见的可能导致内存泄漏的代码
1)如果仅仅使用手动创建的线程,就算没有调用ThreadLocal的remove方法清理数据,也不会产生内存泄漏。因为当线程被回收时,ThreadLocal也同样被回收。但是如果使用线程池就不一定了,如何线程未被回收则ThreadLocal对象会持续保留在内存中导致内存泄漏,所以线程方法执行完,一定要调用ThreadLocal中的remove方法清理对象。
2)如果大量的数据在静态变量中被长期引用,数据就不会被释放,如果这些数据不再使用,就可能造成内存泄漏,所有尽量减少将对象长时间的保存在静态变量中,如果不再使用,必须将对象删除(比如在集合中)或者将静态变量设置为null。
并发请求
诊断问题
当堆内存溢出时,需要在堆内存溢出时将整个堆内存保存下来,生成内存快照(Heap Profile)文件。
生成内存快照的Java虚拟机参数:-XX:+HeapDumpOnOutOfMemoryError
:发生OutOfMemoryError错误时,自动生成hprof内存快照文件。-XX:HeapDumpPath=
:指定hprof文件的输出路径。
获取到hprof文件后可使用MAT(https://eclipse.dev/mat/downloads.php)分析工具分析内存泄漏的根源
MAT原理 –支配树
获取运行时快照
在程序员开发用的机器内存范围之内的快照文件,直接使用MAT打开分析即可。但是经常会遇到服务器上的 程序占用的内存达到10G以上,开发机无法正常打开此类内存快照,此时需要下载服务器操作系统对应的 MAT。