说明:当项目因JVM内存溢出崩溃时,会生成一个hprof
文件,本文介绍如何手动生成一个这样的文件,用于学习分析。
创建项目
创建一个简单的Spring Boot项目,如下:
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;
@RestController
public class DemoController {
@GetMapping("/error")
public void hello() {
// 在JVM启动参数中添加以下选项:
// -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/path/to/dump/directory
// 或者使用代码设置:
System.setProperty("java.lang.Integer.IntegerCache.high", "20000");
System.setProperty("com.sun.management.jmxremote", "");
// 触发内存不足错误
try {
List<Integer> list = new ArrayList<>();
while (true) {
list.add(new Integer(100));
}
} catch (OutOfMemoryError e) {
System.out.println("OutOfMemoryError triggered: " + e.getMessage());
// 这里可以添加处理代码,如记录日志等
}
}
}
pom.xml,如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.12</version>
<relativePath/>
</parent>
<groupId>com.hezy</groupId>
<artifactId>hprof_demo</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
启动
Maven,点package
,打成一个jar包,如下:
然后放服务器上,运行,注意设置下参数,把JVM堆栈内存设置小一点,不要把服务器搞崩了。
java -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home -Xms16m -Xms16m -Xmn16m -jar /home/hprof_demo-1.0-SNAPSHOT.jar
-XX:HeapDumpPath=/home
,表示hprof
文件存放的路径;
启动后,接口调一下,然后坐等文件,如下:
然后,用JDK(JDK 8)自带的jvisualvm
工具装载这个文件,如下:
总结
本文介绍了如何手动生成一个JVM内存溢出的文件,即使用JDK8自带的内存分析工具打开此文件。