前段时间,一个网友问我会不会 jmap,我说了解一点。然后他说公司另外一个项目组里一个妹子,程序老出问题,我想用 jmap 帮他搞定。然后我就给他说如何使用,没想到他今天告诉我,他恋爱了,女朋友就是他帮忙解决问题的那个妹子。
大家感觉我瞎扯,其实是真事。加群比较早的网友可能还有印象,群里有一个网名叫小灰灰的小伙伴,就是天天在群里帮助大家解决问题,最终在群里收获了幸福。我们同在上海,还一起吃过饭,他女朋友还挺漂亮的,现在小孩都非常大了。我记得他还特意的在群里发过红包,今天想起东北男孩的印象仍然历历在目。
好了,废话不多扯了,回到主题,我们今天来学习学习 jmap 吧!
jmap 全称 Java Memory Map,是 Java 虚拟机自带的一种内存映像工具。
Oracle 将 jma p描述为一种“输出进程、核心文件、远程调试服务器的共享对象内存映射和堆内存细节”的程序。通过它可以查看内存中对象实例,从而解决程序出现不正常的高内存负载、频繁无响应或内存溢出等问题。
看过前面文章的网友可能都知道,学习命令之前,我们都可以通过 -help 或 -h 来查看一个命令的帮助信息。jmap 同样提供的有帮忙文档。
~ jmap -help Usage: jmap [option] <pid> (to connect to running process) jmap [option] <executable <core> (to connect to a core file) jmap [option] [server_id@]<remote server IP or hostname> (to connect to remote debug server) where <option> is one of: <none> to print same info as Solaris pmap -heap to print java heap summary -histo[:live] to print histogram of java object heap; if the "live" suboption is specified, only count live objects -clstats to print class loader statistics -finalizerinfo to print information on objects awaiting finalization -dump:<dump-options> to dump java heap in hprof binary format dump-options: live dump only live objects; if not specified, all objects in the heap are dumped. format=b binary format file=<file> dump heap to <file> Example: jmap -dump:live,format=b,file=heap.bin <pid> -F force. Use with -dump:<dump-options> <pid> or -histo to force a heap dump or histogram when <pid> does not respond. The "live" suboption is not supported in this mode. -h | -help to print this help message -J<flag> to pass <flag> directly to the runtime system
各个参数解释如下:
- option:选项参数。
- pid:需要打印配置信息的进程 ID。
- executable:产生核心 dump 的 Java 可执行文件。
- core:需要打印配置信息的核心文件。
- server-id:可选的唯一 id,如果相同的远程主机上运行了多台调试服务器,用此选项参数标识服务器。
- remote server IP or hostname:远程调试服务器的IP地址或主机名。
option
- no option:查看进程的内存映像信息,类似 Solaris pmap 命令。
- heap:显示 Java 堆详细信息
- histo[:live]:显示堆中对象的统计信息
- clstats:打印类加载器信息
- finalizerinfo:显示在 F-Queue 队列等待 Finalizer 线程执行 finalizer 方法的对象
- dump:<dump-options>:生成堆转储快照
- F:当 -dump 没有响应时,使用 -dump 或者 -histo 参数. 在这个模式下,live 子参数无效.
- help:打印帮助信息
- J<flag>:指定传递给运行 jmap 的 JVM 的参数
使用 jmap 这个命令需要注意的是,如果你的 JAVA_HOME/bin/ 目录,没有加入 path 中,则无法做到在任意目录下使用 jmap 这个命令。如果加入到了 path 中,可以使用 whereis jmap 查看具体的命令路径。
~ whereis jmap /usr/bin/jmap ~
jmap pid 用来查看进程的内存映像信息,类似 Solaris pmap 命令。
~ jps 1170 Jps 755 RemoteMavenServer 708 1160 Launcher 1161 Application ~ jmap 1161 Attaching to process ID 1161, please wait... Error attaching to process: sun.jvm.hotspot.debugger.DebuggerException: Can't attach symbolicator to the process sun.jvm.hotspot.debugger.DebuggerException: sun.jvm.hotspot.debugger.DebuggerException: Can't attach symbolicator to the process at sun.jvm.hotspot.debugger.bsd.BsdDebuggerLocal$BsdDebuggerLocalWorkerThread.execute(BsdDebuggerLocal.java:169) at sun.jvm.hotspot.debugger.bsd.BsdDebuggerLocal.attach(BsdDebuggerLocal.java:287)
注意,在 mac 下第一次使用这个命令,可能会弹框让你输入计算机密码,之后在使用则不会有这个弹框。
jmap -heap pid 命令显示 Java 堆详细信息。打印一个堆的摘要信息,包括使用的 GC 算法、堆配置信息和各内存区域内存使用信息。
map -heap 1161 Attaching to process ID 1161, please wait... Debugger attached successfully. Server compiler detected. JVM version is 25.181-b13 using thread-local object allocation. Parallel GC with 4 thread(s) Heap Configuration: MinHeapFreeRatio = 0 MaxHeapFreeRatio = 100 MaxHeapSize = 1073741824 (1024.0MB) NewSize = 42991616 (41.0MB) MaxNewSize = 357564416 (341.0MB) OldSize = 87031808 (83.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 = 60293120 (57.5MB) used = 44166744 (42.120689392089844MB) free = 16126376 (15.379310607910156MB) 73.25337285580842% used From Space: capacity = 5242880 (5.0MB) used = 0 (0.0MB) free = 5242880 (5.0MB) 0.0% used To Space: capacity = 14680064 (14.0MB) used = 0 (0.0MB) free = 14680064 (14.0MB) 0.0% used PS Old Generation capacity = 120061952 (114.5MB) used = 19805592 (18.888084411621094MB) free = 100256360 (95.6119155883789MB) 16.496143590935453% used 20342 interned Strings occupying 1863208 bytes.
jmap -histo:live pid 显示堆中对象的统计信息。其中包括每个 Java 类、对象数量、内存大小(单位:字节)、完全限定的类名。打印的虚拟机内部的类名称将会带有一个’*’前缀。如果指定了 live 子选项,则只计算活动的对象。
jmap -clstats pid 打印类加载器信息。-clstats 是 -permstat 的替代方案,在 JDK8 之前,-permstat 用来打印类加载器的数据
打印 Java 堆内存的永久保存区域的类加载器的智能统计信息。对于每个类加载器而言,它的名称、活跃度、地址、父类加载器、它所加载的类的数量和大小都会被打印。此外,包含的字符串数量和大小也会被打印。
jmap -finalizerinfo pid 打印等待终结的对象信息。
jmap -dump:format=b,file=heapdump.phrof pid 生成堆转储快照 dump 文件。以 hprof 二进制格式转储 Java 堆到指定 filename 的文件中。live 子选项是可选的。如果指定了 live 子选项,堆中只有活动的对象会被转储。想要浏览 heap dump,你可以使用 jhat(Java 堆分析工具)读取生成的文件。
执行这个命令需要注意,JVM 会将整个 heap 的信息 dump 写入到一个文件,heap 如果比较大的话,就会导致这个过程比较耗时,并且执行的过程中为了保证 dump 的信息是可靠的,所以会暂停应用,线上系统慎用。
jmap 输出中 class name 非自定义类的说明。
以上内容,大家可以参考我的这些文章《使用VisualVM对JAVA程序进行性能分析及调优》、《jvm hs_err_pid.log 文件分析工具 CrashAnalysis 使用教程》、《jvm crash(崩溃)文件 hs_err_pid.log 分析教程》进行深度学习。
: » 搞定 jmap,意外收获一个女朋友!
原创文章,作者:Maggie-Hunter,如若转载,请注明出处:https://blog.ytso.com/251989.html