Fork me on GitHub

Java程序运行状态的监控

写在前面:

该系列文章,主要是为了深入学习Java完成的一条链,推荐阅读的整体顺序为:Java的内存模型(根源),一个java文件被执行的历程一个Java类的加载Java的垃圾回收机制及算法Linux(六):系统运维常用命令   Java程序运行状态的监控(实用,定位Java程序问题)

JVM的内存模型

在进行GC的时候,不考虑方法区和栈区的部分,因为在java中,垃圾回收主要是针对对象,也就是堆区内存,如上图,堆内存在实际中是分层的;实质上是分为三大块,即新生代(YoungGen)、老年代(Old Memory)、永久区(Perm),新生代又细分为伊甸区(Eden)、生还区(S0、S1),其中伊甸区主要是存放刚诞生的对象(即代码中新new出的对象),S1,S2主要存放新生代经过垃圾清理后存活的对象;

注:这里用的是老图,永久区(Perm)在Java8已经被取缔了

垃圾回收的过程

垃圾回收即GC,主要分为两种,一种为Minor GC,也叫YGC,是最频繁的GC,发生在新生代,Java应用在运行过程中会大量的创建对象,这些对象可能用完即销毁,所以基本在新生代就被回收了。另一种称为Major GC,主要发生在老年代;还有一个含糊不定的概念,即FullGC,大众理解的话,当老年代也满了,则会对整个堆内存进行全量的回收。但是实际情况中,我们主要看的是gc.log日志,其中也会发现在部分gc日志头中也有Full GC字眼,此处表示含义是在这次GC的全过程中,都是STW的状态,也就是说在这次GC的全过程中所有用户线程都是处于暂停的状态。

STW状态:

stop the world指的是用户线程在运行至安全点(safe point)或安全区域(safe region)之后,就自行挂起,进入暂停状态,对外的表现看起来就像是全世界都停止运转了一样,而不论何种gc算法,不论是minor gc还是major gc都会stop the world,区别只在于stop the world的时间长短。

当发生YGC,新生代中没有被任何其他对象所引用的对象将会从内存中被清除,还被其他对象引用的则放到幸存者区。当发生多次YGC,在S0、S1区多次没有被清楚的对象,则会被移到老年代区域。当老年代区域被占满的时候,则会发送Major GC。

监控命令

jps命令:虚拟机进程状况

查看所有的jvm进程,包括进程ID,进程启动的路径等等。

命令格式

jps [option]

参数选项

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

jstat命令:虚拟机统计信息监视工具

jstat(JVM Statistics Monitoring Tool)是用于监视虚拟机各种运行状态信息的命令行工具。它可以显示本地或者远程[1]虚拟机进程中的类加载、内存、垃圾收集、即时编译等运行时数据,在没有GUI图形界面、只提供了纯文本控制台环境的服务器上,它将是运行期定位虚拟机性能问题的常用工具。
命令格式

jstat [ option vmid [interval[s|ms] [count]] ]

参数option为命令选项,vmid则是通过jps获取到的jvm运行号,参数interval和count代表查询间隔和次数,如果省略这2个参数,说明只查询一次。如果每秒进行10次监听,则命令为 jstat -XX vmid 1000 10

 参数选项

参数 作用
-class 监视类加载、卸载数量,总空间以及类装载所耗费的时间
-gc 监视java堆状况,包括Eden区、2个survival区、老年代,永久代等的容量,已用空间,垃圾收集时间合计等信息。
-gccapacity 监视内容与-gc基本相同,但输出主要关注java堆各个区域所用到的最大、最小空间。
-gcutil 监视内容与-gc基本相同,单输出主要关注已用空间占总空间的百分比。
-gccause 与-gcutil功能一样,但是会额外输出导致上一次垃圾收集产生的原因。
-gcnew 监视新生代垃圾收集状况
-gcnewcapacity 监视内容与-gcnew基本相同,输出主要关注使用到的最大、最小空间。
-gcold 监视老年代垃圾收集状况。
-gcoldcapacity 监视内容与-gcold基本线头,输出主要关注使用的最大、最小空间。
-gcpermcapacity 输出永久代用到的最大、最小空间。
-compiler 输出即时编译器编译过的方法、耗时等信息。
-printtcompilation 输出已经被即时编译的方法。

以上实际使用过程中,并不会全部用到,较为常用的主要为-class、-gc、-gcutil;

执行样例

-class

返回解释:

#Loaded 类加载数量
#Bytes  加载的大小(k) 
#Unloaded 类卸载的数量 
#Bytes 卸载的大小(k) 
#Time 时间花费在执行类加载和卸载操作

-gc

-gcutil

返回解释:

#S0C 生还者区0 容量(KB)
#S1C 生还者区1 容量(KB)
#S0U 生还者区0 使用量(KB)
#S1U 生还者区1 使用量(KB)
#EC 伊甸园区容量(KB)
#EU 伊甸园区使用量(KB) 
#OC 老年区容量(KB)
#OU 老年区使用量(KB)
#PC 永久区容量(KB) 
#PU 永久区使用量(KB)
#YGC 新生代GC次数
#YGCT 新生代GC时间
#FGC full GC 事件的次数
#FGCT full GC的时间 
#GCT 总GC时间

jinfo:Java配置信息工具

jinfo(Configuration Info for Java)的作用是实时查看和调整虚拟机各项参数。使用jps命令的-v参数可以查看虚拟机启动时显式指定的参数列表。

jstack:Java堆栈跟踪工具

jstack(Stack Trace for Java)命令用于生成虚拟机当前时刻的线程快照(一般称为threaddump或者javacore文件)。线程快照就是当前虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的目的通常是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间挂起等,都是导致线程长时间停顿的常见原因。线程出现停顿时通过jstack来查看各个线程的调用堆栈,就可以获知没有响应的线程到底在后台做些什么事情,或者等待着什么资源。
命令格式:

jstack [ option ] vmid

参数选项:

参数 作用
-L 除堆栈外,显示关于锁的附加信息。
-F 当正常输出的请求不被响应时,强制输出线程堆栈

 

执行样例:

 

posted @ 2022-08-24 14:29  糖拌西红柿  阅读(1823)  评论(0编辑  收藏  举报