内存问题排查总结
堆内存dump
1 jmap ‐dump:format=b,file=eureka.hprof 14660
可以配置自动 dump 文件,在内存溢出的时候会自动 dump 文件。
-XX:+HeapDumpOnOutOfMemoryError
比如应用的启动脚本,开启自动 dump 文件。
exec java -classpath $CLASSPATH -Xms1024m -Xmx2048m
-XX:+HeapDumpOnOutOfMemoryError
-Dquery.type=es
-Dfile.encoding=UTF-8 org.vlis.cloudmonitor.server.ApiServerApplication $*
使用MAT排查内存泄漏
测试代码
java
private static ExecutorService executorService = Executors.newFixedThreadPool(500);
@GetMapping("/object")
public void testObject() {
for (int i = 0; i < 100; i++) {
executorService.submit(() -> {
//对象列表更明显
List<UserVo> userVoList = userService.getUserVoList();
System.out.println(userVoList.size());
});
}
}
java
public class UserService {
//不手动remove
private static ThreadLocal<List<UserVo>> threadLocal = new ThreadLocal<>();
public List<UserVo> getUserVoList() {
if (threadLocal.get() == null) {
List<UserVo> list = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
list.add(UserVo.getTestData());
}
threadLocal.set(list);
}
return threadLocal.get();
}
}
测试结论
no-gc
查看对象个数,50w个
结合MAT给出的内存泄漏推测,有50w个对象。
gc
使用 jconsole手动gc之后,MAT分析的还是有50w个对象。
GC无法有效回收线程里,存放到ThreadLocal里面的对象,造成了内存泄漏。