1.如何分析jvm内存溢出呢
我们经常用visualVm监控Jvm的内存,cpu,线程的使用情况,通常可以根据内存不断增长来判断内存是否存在不释放。但是我们不可能时时盯着去看,这里涉及jvm堆内存配置,堆内存参数配置和调优会在其他章节编写。
如果真是内存溢出了,线上出现的我们需要配置JVm内存溢出,建议线上一定要配置此参数XX:+HeapDumpOnOutOfMemoryError,否则到时不好分析线上问题。
-Xms100m -Xmx100m -XX:+HeapDumpOnOutOfMemoryError
2.编写我们自己的代码
接下来我们模拟内存溢出代码
@Getter
@Setter
@ToString
public class HeapBean {
private int userId;
private String name;
private String phone;
}
package com.es.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RestController
public class HeapController {
private List<HeapBean> userlist = new ArrayList<>();
private Map hashMap=new HashMap<>();
//堆区内存溢出
@GetMapping("/heapOom")
public void heapOverTest() {
int i = 0;
while (true) {
//heaplist.add(new heapBean());
hashMap.put(i, new HeapBean());
i++;
}
}
}
本地启动代码,后请求实际地址。
运行到一定时间,就会生成hprof文件。
java.lang.OutOfMemoryError: GC overhead limit exceeded Dumping heap to java_pid16868.hprof ... Heap dump file created [171733163 bytes in 0.854 secs] Exception in thread "File Watcher" java.lang.OutOfMemoryError: GC overhead limit exceeded at java.lang.String.toLowerCase(String.java:2647) at java.io.WinNTFileSystem.hashCode(WinNTFileSystem.java:640) at java.io.File.hashCode(File.java:2132) at org.springframework.boot.devtools.filewatch.FileSnapshot.hashCode(FileSnapshot.java:72) at java.util.HashMap.hash(HashMap.java:338) at java.util.HashMap.put(HashMap.java:611) at java.util.HashSet.add(HashSet.java:219) at org.springframework.boot.devtools.filewatch.DirectorySnapshot.collectFiles(DirectorySnapshot.java:70) at org.springframework.boot.devtools.filewatch.DirectorySnapshot.collectFiles(DirectorySnapshot.java:67)
通过everything找到这个文件.
3.需要用到eclipse Memory Analyzer工具
Eclipse Memory Analyzer(简称MAT)是一个功能丰富且操作简单的JVM Heap Dump分析工具,可以用来辅助发现内存泄漏减少内存占用。
点击下载
点击“MemoryAnalyzer.exe”,启动分析内存工具。
打开java_pid16868.hprof文件
按照红色点击确认,看到占用最多的4.5m。
往下移动看到具体占用的类
点击details,看到我们自己的类。
继续往下,看到对象的总数和占用的堆内存。
4.总结
总结最后到时HeapControler中的hashMap导致的内存溢出。