JVM虚拟机监控与诊断工具 - Java技术债务


jps:查看正在运行的 Java 进程

显示指定系统内所有 HotSpot 虚拟机进程

语法:

jps [options]
-q	只输出LVMID,省略主类的名称
-m	输出虚拟机进程启动时传递给主类main()函数的参数
-l	输出主类的全名,如果进程执行的是jar包,则输出jar路径
-v	输出虚拟机进程启动时的JVM参数

* 如果程序参数中添加了 -xx:UsePerfData 参数,命令就无法查询该程序的进程号

jstat:查看 JVM 统计信息

可以显示本地或者远程虚拟机进程中的类加载、内存、垃圾手机、即时编译等运行时数据。

语法:

jstat  -

JVM常用监控工具解释以及使用 - Java技术债务

堆内存 = 年轻代 + 年老代 + 永久代

年轻代 = 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] >
jmap [option] [server_id@]

[option]:
		* -dump: 生成 dump 文件
		* -finalizerinfo: 显示在 F-Queue 中等待 Finalizer 线程执行 finalize 方法的对象
		* -heap: 输出整个堆空间的详细信息,包括 GC 的使用、堆配置信息,以及内存的使用信息等。
		* -histo: 输出堆空间中对象的统计信息,包括类、实例数量和合计容量
		* -permstat: 以 ClassLoader 为统计口径输出永久代的内存状态信息
		* -F: 当虚拟机进程对 -dump 选项没有任何响应时,强制执行生成 dump 文件

使用jmap -heap pid查看进程堆内存使用情况,包括使用的GC算法、堆配置参数和各代中堆内存使用情况。

JVM常用监控工具解释以及使用 - Java技术债务

使用jmap -histo[:live] pid [| more]查看堆内存中的对象数目、大小统计直方图,如果带上live则只统计活对象。注意:此时会先old gc然后再进行统计,避免在线上环境使用。

JVM常用监控工具解释以及使用 - Java技术债务

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 

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

JVM常用监控工具解释以及使用 - Java技术债务

JVM常用监控工具解释以及使用 - Java技术债务

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 '.
  • 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
  • VM.flags 可以获取JVM的配置参数信息

jstatd:远程主机信息收集

之前的指令只涉及到监控本机的Java应用程序,而在这些工具中,一些监控工具也支持对远程计算机的监控(如jpsjstat)。为了启用远程监控,则需要配合使用jstatd 工具。命令jstatd是一个RMI服务端程序,它的作用相当于代理服务器,建立本地计算机与远程监控工具的通信。jstatd服务器将本机的Java应用程序信息传递到远程计算机。

   登录后才可以发表评论呦...

专注分享Java技术干货,包括
但不仅限于多线程、JVM、Spring Boot
Spring Cloud、 Redis、微服务、
消息队列、Git、面试题 最新动态等。

想交个朋友吗
那就快扫下面吧


微信

Java技术债务

你还可以关注我的公众号

会分享一些干货或者好文章

Java技术债务