文章目录
jps:查看正在运行的 Java 进程
显示指定系统内所有 HotSpot 虚拟机进程
语法:
jps [options]
-q 只输出LVMID,省略主类的名称
-m 输出虚拟机进程启动时传递给主类main()函数的参数
-l 输出主类的全名,如果进程执行的是jar包,则输出jar路径
-v 输出虚拟机进程启动时的JVM参数
* 如果程序参数中添加了 -xx:UsePerfData 参数,命令就无法查询该程序的进程号
jstat:查看 JVM 统计信息
可以显示本地或者远程虚拟机进程中的类加载、内存、垃圾手机、即时编译等运行时数据。
语法:
jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]
<optiopn>:
* class: 显示 ClassLoader 的相关信息: 类装载、占用空间、卸载数量、卸载类大小、装载类所消耗的时间。
gc 相关 ↓
* gc: 显示与 GC 相关的堆信息。
* gccapacity: 显示内容与 -gc 基本相同,但输出主要关注 Java 堆各个区域使用的最大、最小空间。
* gcutil: 显示内容与 -gc 基本相同,但输出主要关注已使用空间占总空间的百分比。
* gccause: 与 -gcutil 功能一样,但是会额外输出导致最后一次或当前正在发生 GC 产生的原因。
* gcnew: 显示新生代 GC 状况。
* gcnewcapacity: 显示内容与 -gcnew 基本相同,输出主要关注使用到的最大、最小空间。
* gcold: 显示老年代 GC 状况。
* gcoldcapacity: 显示内容与 -gcold 基本相同,输出主要关注使用到的最大、最小空间
* gcpermcapacity: 显示永久代使用到的最大、最小空间
JIT 相关 ↓
* compiler: 显示 JIT 编译器编译过的方法、耗时等信息
* printcompilation: 显示已经被 JIT编译过的方法
-t: 进程运行的时间
-h<lines>: 在周期性输出数据时,每隔多少行,就输出一个表头
<vmid>: 进程id
<interval>:
查询间隔,位为毫秒
<count>:
查询总次数(和 interval 搭配使用)
堆内存 = 年轻代 + 年老代 + 永久代
年轻代 = Eden区 + 两个Survivor区(From和To)
S0C、S1C、S0U、S1U:Survivor 0/1区容量(Capacity)和使用量(Used)
EC、EU:Eden区容量和使用量
OC、OU:年老代容量和使用量
PC、PU:永久代容量和使用ssss量
YGC、YGT:年轻代GC次数和GC耗时
FGC、FGCT:Full GC次数和Full GC耗时
GCT:GC总耗时
top -Hp 1容器中所有进程占用CPU内存的情况
注意:如何使用
jstat -gc
来判断是否存在内存泄露:
1、在长时间运行的 Java 程序中,使用 jstat -gc 命令来连续获取多行 GC 内存数据,并取这几行数据列中 OU 列的最小值(即已占用的老年代内存);
2、每隔一段较长时间,重复上述操作,获取多组 OU 列最小值。如果这些值呈现上涨趋势,则说明该 Java 程序的老年代内存已使用量在不断上涨,这意味着无法回收的对象在不断增加,因此有可能存在内存泄露。如何使用
jstat -gc -t
来判断堆压力:
我们可以比较 Java 进程的启动时间以及总 GC 时间(GCT列),或则两次测量时间的间隔时间以及总 GC 时间的增量,来得出 GC 时间占运行时间的比例,如果比例较高,说明堆压力大,如果接近 90 %,说明随时都有可能抛出 OOM。
jmap:导出内存映像文件&内存使用情况
获取 dump 文件(堆转储快照的二进制文件)以及获取 Java 进程的内存相关信息,包括 Java 堆各区域的使用情况、堆中对象的统计信息、类加载信息等。(官网推荐用 jcmd
)
语法:
jmap [option] pid
jmap [option] <executable <core>>
jmap [option] [server_id@]<remote server IP or hostname>
[option]:
* -dump: 生成 dump 文件
* -finalizerinfo: 显示在 F-Queue 中等待 Finalizer 线程执行 finalize 方法的对象
* -heap: 输出整个堆空间的详细信息,包括 GC 的使用、堆配置信息,以及内存的使用信息等。
* -histo: 输出堆空间中对象的统计信息,包括类、实例数量和合计容量
* -permstat: 以 ClassLoader 为统计口径输出永久代的内存状态信息
* -F: 当虚拟机进程对 -dump 选项没有任何响应时,强制执行生成 dump 文件
使用jmap -heap pid查看进程堆内存使用情况,包括使用的GC算法、堆配置参数和各代中堆内存使用情况。
使用jmap -histo[:live] pid [| more]查看堆内存中的对象数目、大小统计直方图,如果带上live则只统计活对象。注意:此时会先old gc然后再进行统计,避免在线上环境使用。
instance 是对象的实例个数
bytes 是总占用的字节数
class name 对应的就是 Class 文件里的 class 的标识
B 代表 byte
C 代表 char
D 代表 double
F 代表 float
I 代表 int
J 代表 long
Z 代表 boolean
前边有 [ 代表数组, [I 就相当于 int[]
对象用 [L+ 类名表示
用jmap
把进程内存使用情况dump
到文件中,再用jhat分析查看。jmap进行dump命令格式如下:
jmap -dump:format=b,file=/tmp/dump.dat pid
dump
出来的文件可以用MAT、VisualVM等工具查看,这里用jhat查看:
jhat -port 9998 /tmp/dump.dat
注意如果Dump文件太大,可能需要加上-J-Xmx512m这种参数指定最大堆内存,即jhat -J-Xmx512m -port 9998 /tmp/dump.dat。然后就可以在浏览器中输入主机地址:9998查看了
jhat:JDK 自带堆分析工具
用于跟 jmap 搭配使用,解析 jmap 生成的 dump 文件。
jhat 命令在 JDK9 及之后中已经被删除,建议使用 VisualVM 代替
语法:
jhat <filename.hprof>
jstack:打印 JVM 线程快照
jstack可以定位到线程堆栈,根据堆栈信息我们可以定位到具体代码,所以它在JVM性能调优中使用得非常多。下面我们来一个实例找出某个Java进程中最耗费CPU的Java线程并定位堆栈信息,用到的命令有ps、top、printf、jstack、grep。
语法:
jstack [option] pid
[option]:
* -F: 当正常输出的请求不被响应时,强制输出线程堆栈
* -l: 除堆栈外,显示关于锁的附加信息
* -m: 如果调用本地方法的话,可以显示 C/C++ 的堆栈
例: jstack -l 17792
在 thread dump 中,主要留意以下几种状态
- 死锁,Deadlock
- 等待资源,Waiting on condition
- 等待获取监视器,Waiting on monitor entry
- 阻塞,Blocked
- 执行中,Runnable
- 暂停,Suspended
- 对象等待中,Object.wait() 或 TIMED_WAITING
- 停止,Parked
jinfo:实时查看和修改 JVM 配置参数
查询虚拟机配置的参数信息,也可用于调整虚拟机的参数配置
jinfo [options] pid
[options]:
* no option: 不输入 option 时,会输出全部的参数和系统属性
* -flag name: 输出对应名称的参数
* -flag [+/-]name: 开启或关闭对应名称的参数,只有被标记为 manageable 的参数才可以被动态修改(针对的是 boolean 类型的参数)
* -flag name=value: 设定对应名称的参数(针对的是 值 类型的参数)
* -flags: 输出全部的参数
* -sysprops: 输出系统属性
------- 拓展 -------
命令:
java -XX:+PrintFlagsInitial: 查询所有 JVM 参数启动的初始值
java -XX:+PrintFlagsFinal: 查询所有 JVM 参数的最终值
java -XX:+PrintCommandLineFlags: 查询已经被用户或者 JVM 设置过的详细的 XX 参数的名称和值
jcmd:多功能命令行
在 JDK7 之后,新增的命令工具,可以实现前面除了 jstat
之外所有命令的功能,如导出堆、内存使用、查看 Java 进程、导出线程信息、执行 GC、JVM 运行时间等。(jcmd 拥有 jmap 大部分功能,官网推荐用 jcmd)
语法:
jcmd -l 列出所有的JVM 进程,跟 jps 命令相同
jcmd pid help 列出所有支持的命令
jcmd pid [help 查出来的具体指令]
root@xmars-ai-center-54cd744986-nxbfh:/# jcmd 8 help
8:
The following commands are available:
VM.unlock_commercial_features
JFR.configure
JFR.stop
JFR.start
JFR.dump
JFR.check
VM.native_memory
ManagementAgent.stop
ManagementAgent.start_local
ManagementAgent.start
VM.classloader_stats
GC.rotate_log
Thread.print
GC.class_stats
GC.class_histogram
GC.heap_dump
GC.finalizer_info
GC.heap_info
GC.run_finalization
GC.run
VM.uptime
VM.dynlibs
VM.flags
VM.system_properties
VM.command_line
VM.version
help
For more information about a specific command use 'help <command>'.
Thread.print
可以替换jstack
指令GC.class_histogram
可以替换jmap
中的histo
操作GC.heap_dump
可以替换jmap
中的dump
操作GC.run
可以查看GC的执行情况VM.uptime
可以查看程序的总执行时间,可以替换jstat
指令中的t
操作VM.system_properties
可以替换jinfo -sysprops <pid>
VM.flags
可以获取JVM的配置参数信息
jstatd:远程主机信息收集
之前的指令只涉及到监控本机的Java应用程序,而在这些工具中,一些监控工具也支持对远程计算机的监控(如jps
、jstat
)。为了启用远程监控,则需要配合使用jstatd
工具。命令jstatd
是一个RMI服务端程序,它的作用相当于代理服务器,建立本地计算机与远程监控工具的通信。jstatd
服务器将本机的Java应用程序信息传递到远程计算机。
jps:查看正在运行的 Java 进程
显示指定系统内所有 HotSpot 虚拟机进程
语法:
jps [options]
-q 只输出LVMID,省略主类的名称
-m 输出虚拟机进程启动时传递给主类main()函数的参数
-l 输出主类的全名,如果进程执行的是jar包,则输出jar路径
-v 输出虚拟机进程启动时的JVM参数
* 如果程序参数中添加了 -xx:UsePerfData 参数,命令就无法查询该程序的进程号
jstat:查看 JVM 统计信息
可以显示本地或者远程虚拟机进程中的类加载、内存、垃圾手机、即时编译等运行时数据。
语法:
jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]
<optiopn>:
* class: 显示 ClassLoader 的相关信息: 类装载、占用空间、卸载数量、卸载类大小、装载类所消耗的时间。
gc 相关 ↓
* gc: 显示与 GC 相关的堆信息。
* gccapacity: 显示内容与 -gc 基本相同,但输出主要关注 Java 堆各个区域使用的最大、最小空间。
* gcutil: 显示内容与 -gc 基本相同,但输出主要关注已使用空间占总空间的百分比。
* gccause: 与 -gcutil 功能一样,但是会额外输出导致最后一次或当前正在发生 GC 产生的原因。
* gcnew: 显示新生代 GC 状况。
* gcnewcapacity: 显示内容与 -gcnew 基本相同,输出主要关注使用到的最大、最小空间。
* gcold: 显示老年代 GC 状况。
* gcoldcapacity: 显示内容与 -gcold 基本相同,输出主要关注使用到的最大、最小空间
* gcpermcapacity: 显示永久代使用到的最大、最小空间
JIT 相关 ↓
* compiler: 显示 JIT 编译器编译过的方法、耗时等信息
* printcompilation: 显示已经被 JIT编译过的方法
-t: 进程运行的时间
-h<lines>: 在周期性输出数据时,每隔多少行,就输出一个表头
<vmid>: 进程id
<interval>:
查询间隔,位为毫秒
<count>:
查询总次数(和 interval 搭配使用)
堆内存 = 年轻代 + 年老代 + 永久代
年轻代 = Eden区 + 两个Survivor区(From和To)
S0C、S1C、S0U、S1U:Survivor 0/1区容量(Capacity)和使用量(Used)
EC、EU:Eden区容量和使用量
OC、OU:年老代容量和使用量
PC、PU:永久代容量和使用ssss量
YGC、YGT:年轻代GC次数和GC耗时
FGC、FGCT:Full GC次数和Full GC耗时
GCT:GC总耗时
top -Hp 1容器中所有进程占用CPU内存的情况
注意:如何使用
jstat -gc
来判断是否存在内存泄露:
1、在长时间运行的 Java 程序中,使用 jstat -gc 命令来连续获取多行 GC 内存数据,并取这几行数据列中 OU 列的最小值(即已占用的老年代内存);
2、每隔一段较长时间,重复上述操作,获取多组 OU 列最小值。如果这些值呈现上涨趋势,则说明该 Java 程序的老年代内存已使用量在不断上涨,这意味着无法回收的对象在不断增加,因此有可能存在内存泄露。如何使用
jstat -gc -t
来判断堆压力:
我们可以比较 Java 进程的启动时间以及总 GC 时间(GCT列),或则两次测量时间的间隔时间以及总 GC 时间的增量,来得出 GC 时间占运行时间的比例,如果比例较高,说明堆压力大,如果接近 90 %,说明随时都有可能抛出 OOM。
jmap:导出内存映像文件&内存使用情况
获取 dump 文件(堆转储快照的二进制文件)以及获取 Java 进程的内存相关信息,包括 Java 堆各区域的使用情况、堆中对象的统计信息、类加载信息等。(官网推荐用 jcmd
)
语法:
jmap [option] pid
jmap [option] <executable <core>>
jmap [option] [server_id@]<remote server IP or hostname>
[option]:
* -dump: 生成 dump 文件
* -finalizerinfo: 显示在 F-Queue 中等待 Finalizer 线程执行 finalize 方法的对象
* -heap: 输出整个堆空间的详细信息,包括 GC 的使用、堆配置信息,以及内存的使用信息等。
* -histo: 输出堆空间中对象的统计信息,包括类、实例数量和合计容量
* -permstat: 以 ClassLoader 为统计口径输出永久代的内存状态信息
* -F: 当虚拟机进程对 -dump 选项没有任何响应时,强制执行生成 dump 文件
使用jmap -heap pid查看进程堆内存使用情况,包括使用的GC算法、堆配置参数和各代中堆内存使用情况。
使用jmap -histo[:live] pid [| more]查看堆内存中的对象数目、大小统计直方图,如果带上live则只统计活对象。注意:此时会先old gc然后再进行统计,避免在线上环境使用。
instance 是对象的实例个数
bytes 是总占用的字节数
class name 对应的就是 Class 文件里的 class 的标识
B 代表 byte
C 代表 char
D 代表 double
F 代表 float
I 代表 int
J 代表 long
Z 代表 boolean
前边有 [ 代表数组, [I 就相当于 int[]
对象用 [L+ 类名表示
用jmap
把进程内存使用情况dump
到文件中,再用jhat分析查看。jmap进行dump命令格式如下:
jmap -dump:format=b,file=/tmp/dump.dat pid
dump
出来的文件可以用MAT、VisualVM等工具查看,这里用jhat查看:
jhat -port 9998 /tmp/dump.dat
注意如果Dump文件太大,可能需要加上-J-Xmx512m这种参数指定最大堆内存,即jhat -J-Xmx512m -port 9998 /tmp/dump.dat。然后就可以在浏览器中输入主机地址:9998查看了
jhat:JDK 自带堆分析工具
用于跟 jmap 搭配使用,解析 jmap 生成的 dump 文件。
jhat 命令在 JDK9 及之后中已经被删除,建议使用 VisualVM 代替
语法:
jhat <filename.hprof>
jstack:打印 JVM 线程快照
jstack可以定位到线程堆栈,根据堆栈信息我们可以定位到具体代码,所以它在JVM性能调优中使用得非常多。下面我们来一个实例找出某个Java进程中最耗费CPU的Java线程并定位堆栈信息,用到的命令有ps、top、printf、jstack、grep。
语法:
jstack [option] pid
[option]:
* -F: 当正常输出的请求不被响应时,强制输出线程堆栈
* -l: 除堆栈外,显示关于锁的附加信息
* -m: 如果调用本地方法的话,可以显示 C/C++ 的堆栈
例: jstack -l 17792
在 thread dump 中,主要留意以下几种状态
- 死锁,Deadlock
- 等待资源,Waiting on condition
- 等待获取监视器,Waiting on monitor entry
- 阻塞,Blocked
- 执行中,Runnable
- 暂停,Suspended
- 对象等待中,Object.wait() 或 TIMED_WAITING
- 停止,Parked
jinfo:实时查看和修改 JVM 配置参数
查询虚拟机配置的参数信息,也可用于调整虚拟机的参数配置
jinfo [options] pid
[options]:
* no option: 不输入 option 时,会输出全部的参数和系统属性
* -flag name: 输出对应名称的参数
* -flag [+/-]name: 开启或关闭对应名称的参数,只有被标记为 manageable 的参数才可以被动态修改(针对的是 boolean 类型的参数)
* -flag name=value: 设定对应名称的参数(针对的是 值 类型的参数)
* -flags: 输出全部的参数
* -sysprops: 输出系统属性
------- 拓展 -------
命令:
java -XX:+PrintFlagsInitial: 查询所有 JVM 参数启动的初始值
java -XX:+PrintFlagsFinal: 查询所有 JVM 参数的最终值
java -XX:+PrintCommandLineFlags: 查询已经被用户或者 JVM 设置过的详细的 XX 参数的名称和值
jcmd:多功能命令行
在 JDK7 之后,新增的命令工具,可以实现前面除了 jstat
之外所有命令的功能,如导出堆、内存使用、查看 Java 进程、导出线程信息、执行 GC、JVM 运行时间等。(jcmd 拥有 jmap 大部分功能,官网推荐用 jcmd)
语法:
jcmd -l 列出所有的JVM 进程,跟 jps 命令相同
jcmd pid help 列出所有支持的命令
jcmd pid [help 查出来的具体指令]
root@xmars-ai-center-54cd744986-nxbfh:/# jcmd 8 help
8:
The following commands are available:
VM.unlock_commercial_features
JFR.configure
JFR.stop
JFR.start
JFR.dump
JFR.check
VM.native_memory
ManagementAgent.stop
ManagementAgent.start_local
ManagementAgent.start
VM.classloader_stats
GC.rotate_log
Thread.print
GC.class_stats
GC.class_histogram
GC.heap_dump
GC.finalizer_info
GC.heap_info
GC.run_finalization
GC.run
VM.uptime
VM.dynlibs
VM.flags
VM.system_properties
VM.command_line
VM.version
help
For more information about a specific command use 'help <command>'.
Thread.print
可以替换jstack
指令GC.class_histogram
可以替换jmap
中的histo
操作GC.heap_dump
可以替换jmap
中的dump
操作GC.run
可以查看GC的执行情况VM.uptime
可以查看程序的总执行时间,可以替换jstat
指令中的t
操作VM.system_properties
可以替换jinfo -sysprops <pid>
VM.flags
可以获取JVM的配置参数信息
jstatd:远程主机信息收集
之前的指令只涉及到监控本机的Java应用程序,而在这些工具中,一些监控工具也支持对远程计算机的监控(如jps
、jstat
)。为了启用远程监控,则需要配合使用jstatd
工具。命令jstatd
是一个RMI服务端程序,它的作用相当于代理服务器,建立本地计算机与远程监控工具的通信。jstatd
服务器将本机的Java应用程序信息传递到远程计算机。
- 本文作者:
- 原文链接:
- 版权声明: 本博客所有文章除特别声明外,均采用 进行许可。转载请署名作者且注明文章出处。