JVM工具分析

江枫思渺然 提交于 2019-12-17 23:41:08

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
    在这里插入图片描述
Loaded Bytes Unloaded Bytes Time
已加载类的数量 已加载类的大小(KB) 未加载类数量 未加载类的大小(KB) 本次加载耗费的时间(s)
  1. -gc

1576319874053.png)]

S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
幸存区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)]

NGCMN NGCMX NGC S0C S1C EC OGCMN OGCMX OGC OC MCMN MCMX MC CCSMN CCSMX CCSC YGC FGC
新生代最小容量 新生代最大容量 当前新生代容量 幸存区1容量 幸存区2容量 Eden容量 老年代最小容量 老年代最大你容量 当前老年代大小 老年代容量 元数据最小容量 元数据最大容量 元数据空间容量 压缩类空间最小容量 压缩类空间最大容量 压缩类空间容量 年轻代gc次数 full gc次数
  1. -gcutil
    在这里插入图片描述
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
幸运区1使用占比 幸运区2使用占比 Eden区使用占比 老年代使用占比 元数据使用占比 类压缩空间使用占比 YOUNG GC次数 Young GC耗时 Full GC次数 Full GC耗时 总GC耗时
  1. -gccause
    在这里插入图片描述
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT LGCC GCC
幸运区1使用占比 幸运区2使用占比 Eden区使用占比 老年代使用占比 元数据使用占比 类压缩空间使用占比 YOUNG GC次数 Young GC耗时 Full GC次数 Full GC耗时 总GC耗时 最近一次GC原因 GC次数

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

  1. -gcnew
    在这里插入图片描述

  2. -gcnewcapacity
    在这里插入图片描述

  3. -gcold
    在这里插入图片描述

  4. -gcoldcapacity
    在这里插入图片描述

  5. -compiler
    在这里插入图片描述

Compiled Failed Invalid time failedType FailedMethod
编译过类的数量 失败数量 失效数量 耗时 失败类型 失败方法
  1. -printcompilation
    在这里插入图片描述
Compiled Size Type Method
最近编译方法的数量 最近编译方法的字节码数量 最近编译方法的编译类型 方法名标识

jinfo

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

  1. 查看JVM参数

用法 : jinfo -flag 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 +表示启用该值, jinfo -flag -表示停用该值

在这里插入图片描述

jmap

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

常用选项

选项 作用
-dump 生成Java堆转储快照,格式为:-dump:[live,]format=b,file=,其中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
    在这里插入图片描述
num instances bytes class 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)的位置。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!