前面介绍了jps、jstat命令,下面面我们将继续介绍jmap、jinfo、jstack、jcmd
JVM中性能调优工具功能详解(上)–jps、jstat
jmap允许用户统计目标 Java 进程的堆中存放的 Java 对象,并将它们导出成二进制文件。
命令格式 jmap [options]
没有使用任何选项时,jmap打印共享对象映射。对于加载到目标虚拟机中的每个共享对象,将打印开始地址、映射大小和共享对象文件的完整路径。
clstats | 该子命令将打印类加载器信息 |
---|---|
finalizerinfo | 该子命令将打印正等候回收的对象的信息 |
histo | 该子命令将统计各个类的实例数目以及占用内存,并按照内存使用量从多至少的顺序排列。此外,-histo:live只统计堆中的存活对象 |
dump | 该子命令将导出 Java 虚拟机堆的快照 |
heap | 打印heap的概要信息,GC使用的算法,heap(堆)的配置及JVM堆内存的使用情况 |
jmap -clstats --打印类加载器信息
clstats是-permstat的替代方案,在JDK8之前,-permstat用来打印类加载器的数据
打印Java堆内存的永久保存区域的类加载器的智能统计信息。对于每个类加载器而言,它的名称、活跃度、地址、父类加载器、它所加载的类的数量和大小都会被打印。此外,包含的字符串数量和大小也会被打印。
jmp -finalizerinfo --打印正等候回收的对象的信息
jmap -histo,该子命令将统计各个类的实例数目以及占用内存,并按照内存使用量从多至少的顺序排列。此外,-histo:live只统计堆中的存活对象。
num #instances(实例) #bytes(字节大小) class name(类名)
jmap -dump,该子命令将导出 Java 虚拟机堆的快照。
同样,-dump:live只保存堆中的存活对象。
jmap -dump:live,format=b,file=filename.bin命令,将堆中所有存活对象导出至一个文件之中。这里format=b将使jmap导出与hprof(在 Java 9 中已被移除)、-XX:+HeapDumpAfterFullGC、-XX:+HeapDumpOnOutOfMemoryError格式一致的文件。想要浏览heap dump,你可以使用jhat(Java堆分析工具)读取生成的文件。
jhat会启动一个服务器,我们通过浏览器进行访问。
这个命令执行,JVM会将整个heap的信息dump写入到一个文件,heap如果比较大的话,就会导致这个过程比较耗时,并且执行的过程中为了保证dump的信息是可靠的,所以会暂停应用, 线上系统慎用。
jmap -heap --打印heap的概要信息,GC使用的算法,heap(堆)的配置及JVM堆内存的使用情况
由于jmap将访问堆中的所有对象,为了保证在此过程中不被应用线程干扰,jmap需要借助安全点机制,让所有线程停留在不改变堆中数据的状态。也就是说,由jmap导出的堆快照必定是安全点位置的。这可能导致基于该堆快照的分析结果存在偏差。
举个例子,假设在编译生成的机器码中,某些对象的生命周期在两个安全点之间,那么:live选项将无法探知到这些对象。另外,如果某个线程长时间无法跑到安全点,jmap将一直等下去。上一小节的jstat则不同。这是因为垃圾回收器会主动将jstat所需要的摘要数据保存至固定位置之中,而jstat只需直接读取即可。
jmap(以及接下来的jinfo、jstack和jcmd)依赖于 Java 虚拟机的Attach API,因此只能监控本地 Java 进程。一旦开启 Java 虚拟机参数DisableAttachMechanism(即使用参数-XX:+DisableAttachMechanism),基于 Attach API 的命令将无法执行。反过来说,如果你不想被其他进程监控,那么你需要开启该参数。
用来查看 Java 进程运行的 JVM 参数
命令格式 jinfo [option]
flag [name] | 输出对应名称的参数 |
---|---|
flag [+ -] [name] | 开启或者关闭对应名称的参数 |
flag [name]=[value] | 修改指定参数的值 |
flags | 查看jvm的非默认的参数值 |
sysprops | 输出当前 jvm 进行的全部的系统属性 |
jinfo -flag [name] --可以查看指定的 jvm 参数的值
flag [+| -] [name]| --开启或者关闭对应名称的参数
+开启 例:开启GC日志
jinfo -flag [name]=[value] --修改指定参数的值
注意:jinfo虽然可以在java程序运行时动态地修改虚拟机参数,但并不是所有的参数都支持动态修改
jinfo -flags --查看jvm的非默认的参数值 内存单位为字节
jinfo -sysflags --输出当前 jvm 进行的全部的系统属性
jstack将打印目标 Java 进程中各个线程的栈轨迹、线程状态、锁状况等信息。它还将自动检测死锁。
命令格式 jstack [ option ] pid
-F | 当“jstack[-l]pid”没有响应时,强制堆栈转储 |
---|---|
-l | 打印关于锁的附加信息 |
-m | 打印java和native c/c++框架的所有栈信息.可以打印JVM的堆栈,显示上Native的栈帧,一般应用排查不需要使用 |
jstack -m --打印java和native c/c++框架的所有栈信息.可以打印JVM的堆栈,显示上Native的栈帧
jcmd则是一把瑞士军刀,可以用来实现前面除了jstat之外所有命令的功能。
-l | 列出当前运行的所有JVM |
---|---|
VM.uptime | 查看虚拟机启动时间 |
Thread.print | 打印线程栈信息 |
GC.class_histogram | 查看系统中类统计信息 |
GC.heap_dump /opt/dump.txt | 导出堆信息 |
VM.flags | 获取VM启动参数 |
PerfCounter.print | 所有性能相关数据 |
jcmd GC.class_histogram --查看系统中类统计信息
jcmd GC.heap_dump /opt/dump.txt --导出堆信息
jcmd VM.flags --获取VM启动参数
jcmd PerfCounter.print --所有性能相关数据