Heap Dump内存分析
Heap Dump内存分析
Heap Dump是Java堆内存的快照,用于分析内存泄漏、大对象和内存使用情况。
生成Heap Dump
# jmap命令
jmap -dump:live,format=b,file=heap.hprof <pid>
# OOM时自动生成
java -XX:+HeapDumpOnOutOfMemoryError \
-XX:HeapDumpPath=/tmp/heap.hprof \
-jar app.jar
# jcmd命令
jcmd <pid> GC.heap_dump /tmp/heap.hprof
# 代码中生成
HotSpotDiagnosticMXBean mxBean = ManagementFactory.getPlatformMXBean(
HotSpotDiagnosticMXBean.class);
mxBean.dumpHeap("/tmp/heap.hprof", true);
使用Eclipse MAT分析
Leak Suspects Report
// MAT会自动检测可疑泄漏点
// 示例:大数组持有者
// Problem Suspect 1:
// 16,000 instances of "com.example.entity.User"
// loaded by "app classloader"
// occupy 128,000,000 (60%) bytes.
Dominator Tree
// 按对象保留内存排序
com.example.cache.UserCache @ 0x7ab5c2a80
Retained Heap: 128MB
Shallow Heap: 64B
HashMap @ 0x7ab5c2b00
Retained Heap: 128MB
Object[64000] @ 0x7ab5c2c00
常见内存问题
内存泄漏示例
// 错误:静态集合持有对象引用
public class UserService {
private static final List<User> users = new ArrayList<>(); // 持续增长
public void addUser(User user) {
users.add(user); // 永远不会被GC回收
}
}
// 错误:未关闭的资源
public class FileService {
public void readFile(String path) throws IOException {
InputStream is = new FileInputStream(path);
// 忘记关闭,导致资源泄露
}
}
// 正确:使用try-with-resources
public class FileService {
public void readFile(String path) throws IOException {
try (InputStream is = new FileInputStream(path)) {
byte[] data = is.readAllBytes();
}
}
}
大对象排查
# 使用jmap查看大对象
jmap -histo:live <pid> | head -20
# 输出示例:
# num #instances #bytes class name
# 1: 500000 40000000 [B
# 2: 200000 16000000 java.lang.String
内存配置优化
# 堆内存设置
java -Xms4g -Xmx4g \
-XX:NewRatio=2 \
-XX:SurvivorRatio=8 \
-jar app.jar
# 元空间设置
java -XX:MetaspaceSize=256m \
-XX:MaxMetaspaceSize=512m \
-jar app.jar
代码内存监控
@Component
public class MemoryMonitor {
@Scheduled(fixedRate = 60000)
public void checkMemory() {
Runtime runtime = Runtime.getRuntime();
long maxMemory = runtime.maxMemory();
long totalMemory = runtime.totalMemory();
long freeMemory = runtime.freeMemory();
long usedMemory = totalMemory - freeMemory;
double usagePercent = (double) usedMemory / maxMemory * 100;
if (usagePercent > 80) {
log.warn("内存使用率过高: {}%", usagePercent);
}
}
}
小结
Heap Dump分析是排查内存问题的关键手段,结合MAT工具可快速定位内存泄漏和大对象问题。