一、jmap介绍
jmap是JDK自带的一款用于获取Java应用的heap或类信息快照的命令行工具,它能够让我们更好地了解内存中对象的使用情况,从而方便优化应用程序。
二、jmap常用选项
jmap有多个选项,我们通常会用到以下几个:
-heap
该选项可以让我们获得应用程序的heap大小、占用率等内存信息。例如:
jmap -heap 19321
这条命令会输出进程号19321对应的Java应用的heap信息,例如:
Attaching to process ID 19321, please wait... Debugger attached successfully. Server compiler detected JVM version is 25.102-b14 using thread-local object allocation. Parallel GC with 4 thread(s) Heap Configuration: MinHeapFreeRatio = 40 MaxHeapFreeRatio = 70 MaxHeapSize = 2147483648 (2048.0MB) // 最大可用heap大小 NewSize = 1048576 (1.0MB) // 新生代大小 MaxNewSize = 33554432 (32.0MB) // 新生代最大大小 OldSize = 4194304 (4.0MB) // 老年代大小 NewRatio = 2 SurvivorRatio = 8 MetaspaceSize = 21807104 (20.796875MB) //永久代大小 CompressedClassSpaceSize = 1073741824 (1024.0MB) //压缩类空间大小 MaxMetaspaceSize = 17592186044415 MB G1HeapRegionSize = 0 (0.0MB) Heap Usage: PS Young Generation Eden Space: capacity = 279183360 (266.125MB) // Eden区域容量 used = 36645336 (34.925048828125MB) // 已使用空间 free = 242538024 (231.199951171875MB) // 未使用空间 13.11123171556415% used //空间使用率 ...
-histo[:live]
该选项会输出Java堆内存中的对象信息,包括对象的数量、占用内存大小、类名等。如果加上":live"参数,则只统计存活对象的信息。例如:
jmap -histo 19321
这条命令会输出进程号19321对应的Java应用中对象的统计信息,例如:
num #instances #bytes class name ---------------------------------------------- 1: 183765 474534880 [C // char数组对象 2: 8749 274628312 [B // byte数组对象 3: 21869 164735880 java.lang.String 4: 9350 57402584 [I // int数组对象 5: 310942 49910872 java.util.LinkedHashMap$Entry ...
-dump:[live,]format=b,file=filename
该选项可以生成一个Java堆的dump文件,我们可以用jhat、MAT等工具来解析这个文件,进行一些内存分析。例如:
jmap -dump:live,format=b,file=heapdump.bin 19321
这条命令会生成进程号19321对应Java应用的存活对象的dump文件heapdump.bin。我们可以使用jhat工具来解析这个文件:
jhat heapdump.bin
然后在浏览器中访问http://localhost:7000/即可查看内存分析报告。
三、jmap的优化实践
1. 分析内存泄漏
使用jmap可以针对Java应用程序进行内存泄漏分析。如果应用程序出现了内存泄漏,就可以借助jmap管理Java堆中的对象,通过GC日志、堆转储文件等方式来确定内存泄漏的类型和原因。
下面是一个jmap分析内存泄漏的示例代码:
public class MemoryLeak { private static List