JVM工具分析

JDK监控和故障处理工具

名称主要作用
jps查看系统内所有jvm虚拟机进程
jstat用于收集虚拟机各方面的运行数据
jinfo显示虚拟机配置信息
jmap生成虚拟机内存转储快照(dump 文件)
jhat用于分析dump文件,会建立一个http服务,在7000端口
jstack显示虚拟机线程快照

处理工具详解

jps

常用选项

选项作用
-q只输出LVMID(jvm唯一进程id 一般与物理机进程相同),省略主类名称
-m输出虚拟机进程启动时传递给主类main()函数的参数
-l输出主类的全名,如果进程执行的是Jar包,输出jar路径
-v输出虚拟机进程启动时Jvm参数

详细举例

我本地启动了 IDEA开发工具,启动的idea项目采用了gradle做依赖管理。以此时的环境展示以下命令的结果。

  1. jps

jps查看进程号,和main函数名称。

C:\Users\CaoPengfei\AppData\Roaming\Typora\typora-user-images\1575169392212.png

  1. jps -q 查看进程号,省略Main函数名称。一般该命令不太常用,省略函数名称会导致区分不出你想要关注的进程。

在这里插入图片描述

  1. jps -m 输出虚拟机进程启动时传递给主类main()函数的参数。

手动书写了一个main函数,使用Idea启动他,并在启动时设置program arguments。如下图所示,然后打断点,使主进程停止运行,防止线程结束。
在这里插入图片描述

然后使用Jps -m 可以查看此时的情况。
在这里插入图片描述

  1. jps -l 输出主类的全名,如果进程执行的是Jar包,输出jar路径。

打包了一个本地的springboot项目,项目名称为election_server。这个jar包的位置在target目录下并使用java -jar启动。使用jps -l命令查看
在这里插入图片描述

  1. jps -v 查看输出虚拟机进程启动时Jvm参数

启动了Idea,可以通过jps -v 查看idea启动的参数。本人电脑16G内存,为Idea最大内存分配了4000m,如图可以参数
在这里插入图片描述

注意:使用 jps -help可以查看所有命令的使用介绍, jps支持查看远程服务器的进程,但是不能查看某一具体进程的情况, 比如上图 2312是idea的进程id,使用 jps -v 2312这样是错误的命令

jstat

jstat(JVM Statistics Monitoring Tool) 用于监控虚拟机各种运行状态信息的命令行工具。

常用选项

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

详细举例

​ 本地运行了一服务,先使用jps查看到该服务的进程号,然后使用jstat -option 查看信息.

​ 名词解释:

​ 幸存区1、幸存区2和eden区都属于jvm新生代。三者的比例按照1:1:8来分配,当对象被创建时就会分配到eden区,当eden区容量满了会发生minor GC(Young GC),如若此时存在不能被回收的对象,这些对象被迁移到幸存区1,当再次发生minor GC时,eden区不能被回收的对象会迁移到幸存区2,幸存区1中的对象能被回收的回收掉,不能回收也迁移到幸存区2. 幸存区1和幸存区2保证一个空。当对象进入幸存区后,对象的年龄就开始增加,在1和2之间相互迁移也增加对象的年龄。当对象的年龄超过15(对应的虚拟机参数:-XX:TargetSurvivorRatio),则对象进入到老年代。
​ 在Minor GC过程中,Survivor 可能不足以容纳Eden和另一个Survivor中的存活对象。如果Survivor中的存活对象溢出,多余的对象将被移到老年代,这称为过早提升(Premature Promotion),这会导致老年代中短期存活对象的增长,可能会引发严重的性能问题。再进一步说,在Minor GC过程中,如果老年代满了而无法容纳更多的对象,Minor GC 之后通常就会进行Full GC,这将导致遍历整个Java堆,这称为提升失败(Promotion Failure)

​ old代就是老年代,老年代和新生代的空间容量比为2:1。老年代容量占满好会发生Full GC, Full GC会扫描全堆。

​ 持久代在java 8中被移除了,被替换为了元空间。也是上表中的MC。为什么去除持久代

​ 类压缩空间。要理解一个概念,JVM压缩指针。在java当中,参数传递有一个是引用传递,这个引用就是这里所说的指针,普通对象的指针是存储在类压缩空间中。当引用过多的对象时,可能就会发生

java.lang.OutOfMemoryError: Compressed class space 这个时候需要调CompreseedClassSpaceSize(默认大小为1G)

  1. -class

在这里插入图片描述

LoadedBytesUnloadedBytesTime
已加载类的数量已加载类的大小(KB)未加载类数量未加载类的大小(KB)本次加载耗费的时间(s)
  1. -gc

1576319874053.png)]

S0CS1CS0US1UECEUOCOUMCMUCCSCCCSUYGCYGCTFGCFGCTGCT
幸存区1容量幸存区2容量幸存区1使用量幸存区2使用量eden区容量eden使用量old代容量old待使用量元空间容量元空间使用量类压缩空间容量类压缩空间使用量新生代GC次数新生代GC耗时Full GC次数Full GC时间总共的GC耗时
  1. -gccapacity

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5bTZ6Vgc-1576584409327)(C:\Users\CaoPengfei\AppData\Roaming\Typora\typora-user-images\1576560025481.png)]

NGCMNNGCMXNGCS0CS1CECOGCMNOGCMXOGCOCMCMNMCMXMCCCSMNCCSMXCCSCYGCFGC
新生代最小容量新生代最大容量当前新生代容量幸存区1容量幸存区2容量Eden容量老年代最小容量老年代最大你容量当前老年代大小老年代容量元数据最小容量元数据最大容量元数据空间容量压缩类空间最小容量压缩类空间最大容量压缩类空间容量年轻代gc次数full gc次数
  1. -gcutil

在这里插入图片描述

S0S1EOMCCSYGCYGCTFGCFGCTGCT
幸运区1使用占比幸运区2使用占比Eden区使用占比老年代使用占比元数据使用占比类压缩空间使用占比YOUNG GC次数Young GC耗时Full GC次数Full GC耗时总GC耗时
  1. -gccause

在这里插入图片描述

S0S1EOMCCSYGCYGCTFGCFGCTGCTLGCCGCC
幸运区1使用占比幸运区2使用占比Eden区使用占比老年代使用占比元数据使用占比类压缩空间使用占比YOUNG GC次数Young GC耗时Full GC次数Full GC耗时总GC耗时最近一次GC原因GC次数

-gcnew -gcnewcapacity -gcold -gcoldcapacity 展示内容以上均有说明在此不再列举展示内容

  1. -gcnew

在这里插入图片描述

  1. -gcnewcapacity

在这里插入图片描述

  1. -gcold

在这里插入图片描述

  1. -gcoldcapacity

在这里插入图片描述

  1. -compiler

在这里插入图片描述

CompiledFailedInvalidtimefailedTypeFailedMethod
编译过类的数量失败数量失效数量耗时失败类型失败方法
  1. -printcompilation

在这里插入图片描述

CompiledSizeTypeMethod
最近编译方法的数量最近编译方法的字节码数量最近编译方法的编译类型方法名标识

jinfo

jinfo (Configuration Info for Java)的 作用是实时查看和调整虚拟机各项参数。

  1. 查看JVM参数

用法 : jinfo -flag <name> PID
在这里插入图片描述

查看元空间最大空间,JVM元空间占用的是物理机内存大小,本机内存16G。

  1. 调整JVM参数

并不是所有的参数都允许动态修改,使用以下命令可以查看可以修改参数的内容

  • windows

    java -XX:+PrintFlagsInitial | findstr manageable

  • linux

    java -XX:+PrintFlagsInitial | grep manageable

本人操作系统为Windows

1576565572753

手动修改CMSAborablePrecleanWaitMillis的值由100 改成了101
在这里插入图片描述

如果参数是bool类型,则命令为jinfo -flag +<name>表示启用该值, jinfo -flag -<name>表示停用该值

在这里插入图片描述

jmap

jmap (Memory Map for Java) ,用于生成堆转储快照(一般称为dump文件)。如果不使用jmap命令,还要获取dump,也有一些其他手段,比如配置:-XX:+HeapDumpOnOutOfMemoryError。在Linux上使用kill -3命令,发送进程退出信号,虚拟机会生成dump文件。

常用选项

选项作用
-dump生成Java堆转储快照,格式为:-dump:[live,]format=b,file=<filename>,其中live子参数说明是否只dump出存活的对象
-finalizerinfo显示在F-Queue中等待Finalizer线程执行finalize方法的对象。只在Linux/Solaris平台有效
-heap显示Java堆详细信息,如使用哪种回收器、参数配置、分带状况等。只在Linux/Solaris平台下有效
-histo显示堆中对象统计信息,包括类、实例数量、合计容量
-permstat以ClassLoader为统计口径显示永久代内存状态。只在Linux/Solaris平台有效
-F当虚拟机进程对-dump选项没有响应时,可食用这个选项强制生成dump快照。只在Linux/Solaris平台下有效
  1. -dump

在这里插入图片描述

dump在对应目录下已生成。dump文件生成之后需要分析内容,java提供了在线分析工具jhat,但是不太好用。一般在服务器上面生成dump文件后,在本地分析。jdk本身提供了分析工具。在JAVA_HOME/bin/jvisualvm。双击进入,装载生成的dump文件就可以查看堆信息了。下图为分析刚刚生成的Idea.bin dump文件
在这里插入图片描述

  1. -histo

在这里插入图片描述

numinstancesbytesclass name
数量实例数量合计容量类名称

jhat

用于分析dump文件,不推荐使用。可以使用更专业的visualVM去分析。在这里就不举例如何使用。

jstack

jstack(Stack Trance for Java)命令用于生成虚拟机当前时刻的线程快照(一般称为thread dump 或者java core文件)。线程快照的目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待。

常用选项

选项作用
-F当正常输出的请求不被响应时,强制输出线程堆栈
-l除堆栈外,显示关于锁的附加信息
-m如果调用到本地方法的话,可以显示C/C++的堆栈
/*死循环代码*/
public static void main(String[] args) {
        createBusyThread();
    }

    /**
     * 死循环线程
     */
    public static void createBusyThread(){
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                while (true){

                }
            }
        },"testBusyThread");
        thread.start();
    }

在这里插入图片描述

注意打印内容,提示了类中的20行存在死循环。也就是代码中的while(true)的位置。


yinhaixiang77
6 声望0 粉丝