jvmjvm性能调优

jdk性能监控&故障处理工具

2019-10-04  本文已影响0人  javap

前几篇文章为大家介绍了jvm调优的相关知识点,gc算法,垃圾回收器以及常见的jvm内存配置参数等内容。那么今天将和大家讲一下有关jdk自带的针对jvm调优的工具以及针对实战项目现场进行jvm内存优化!

jdk性能监控工具

方法调用

说到jvm的调优工具,可能很多的人都根本不知道是什么玩意!在这里我会和大家一一的介绍,帮助大家的理解和使用!


方法调用.png

看图可能大家会十分的迷茫,图中的明明都是在window下的可执行的.exe文件呀?为什么是方法调用呢?
这点大家可能真的不理解,在此给大家解释一下,图中也就是我们常用的所有的jvm调优以及监控工具,它们其实就是jdk自己自己写的一些有关底层的监控工具,只不过分模块打包成了不同的.exe可执行文件而已!


jdk监控工具源码.png
tools.jar 转文件类型.zip可以看出结果
tools解压.png

从图中解压可以看出,我们上面所说的所有的jvm调控工具都有相对应的源码,那么就可以很清晰的看出,这就是方法的调用!(这个不太重要,仅供大家理解,有兴趣可以查看源码解读)

jdk监控工具解析

jps

jps的话其实就是jvm虚拟机针对java的系统进程的一个查询,类似于linux系统中的ps -[option]+管道符过滤的功能,这个也是上述所说的监控工具中的入口,也就是最重要的一个,同时也是最简单的一个!(次处注意jps查看java进程的时候,同时jsp也是一个进程,并且jsp的pid也就是进程号一直在变动,所以你不能去分析jps的内存问题)


jps.png
jstat

jstat从字面意思就可以看出,是有关状态的意思,也就是监控此时jvm中某一个java进程的状态信息!一般情况下我们都会采用jstat -gc pid [间隔时间(单位ms)][打印多少次]去查看当前java进程的内存情况进行堆内存变化分析!具体参数如下:


jstat.png
-class (监视类装载、卸载数量、总空间以及耗费的时间)
 jstat -class 4513 
Loaded  加载class的数量
Bytes   class字节大小
Unloaded    未加载class的数量
Bytes   未加载class的字节大小
Time    加载时间
-compiler(输出JIT编译过的方法数量耗时等)
 jstat -compiler 4562 
Compiled    编译数量
Failed  编译失败数量
Invalid     无效数量
Time    编译耗时
FailedType  失败类型
FailedMethod    失败方法的全限定名
-gc(垃圾回收堆的行为统计,常用命令)
 jstat -gc 4562 
S0C survivor0区的总容量
S1C survivor1区的总容量
S0U survivor0区已使用的容量
S1C survivor1区已使用的容量
EC  Eden区的总容量
EU  Eden区已使用的容量
OC  Old区的总容量
OU  Old区已使用的容量
MC  方法区大小(JDK1.8)
MU  方法区使用大小(JDK1.8)
CCSC    压缩类空间大小
CCSU    压缩类空间使用大小
PC  当前perm的容量 (KB)(JDK1.7)
PU  perm的使用 (KB)(JDK1.7)
YGC     新生代垃圾回收次数
YGCT    新生代垃圾回收时间
FGC 老年代垃圾回收次数
FGCT    老年代垃圾回收时间
GCT 垃圾回收总消耗时间
-gccapacity(同-gc,还会输出Java堆各区域使用到的最大、最小空间)
 jstat -gccapacity 4562 
NGCMN   新生代占用的最小空间
NGCMX   新生代占用的最大空间
NGC 当前新生代的空间
OGCMN   老年代占用的最小空间
OGCMX   老年代占用的最大空间
OGC     当前年老代的容量 (KB)
OC      当前年老代的空间 (KB)
MCMN    最小元数据容量
MCMX    最大元数据容量
MC      当前元数据空间大小
CCSMN   最小压缩类空间大小
CCSMX   最大压缩类空间大小
CCSC    当前压缩类空间大小
PGCMN   perm占用的最小空间
PGCMX   perm占用的最大空间
PGC perm的空间 (KB)
YGC     年轻代GC次数
FGC     老年代GC次数
-gcutil(同-gc,输出的是已使用空间占总空间的百分比)
 jstat -gcutil 4562 
S0  幸存区S0当前使用比例
S1  幸存区S1当前使用比例
E   伊甸园区使用比例
O   老年代使用比例
M   元数据区使用比例
CCS 压缩使用比例
YGC 年轻代垃圾回收次数
YGCT    年轻代垃圾回收消耗时间
FGC 老年代垃圾回收次数
FGCT    老年代垃圾回收消耗时间
GCT 垃圾回收消耗总时间
-gcnew(统计新生代行为)
 jstat -gcnew 4562 
S0C 第一个幸存区大小
S1C 第二个幸存区的大小
S0U 第一个幸存区的使用大小
S1U 第二个幸存区的使用大小
TT  对象在新生代存活的次数Tenuring threshold(提升阈值)
MTT 对象在新生代存活的最大次数,最大的tenuring threshold
DSS 期望的幸存区大小,survivor区域大小 (KB)
EC  伊甸园区的大小
EU  伊甸园区的使用大小
YGC 年轻代垃圾回收次数
YGCT    年轻代垃圾回收消耗时间
-gcnewcapacity(新生代与其相应的内存空间的统计)
 jstat -gcnewcapacity 4562 
NGCMN   新生代最小容量
NGCMX   新生代最大容量
NGC 当前新生代容量 (KB)
S0CMX   最大幸存区S0大小 (KB)
S0C 当前幸存区S0空间 (KB)
S1CMX   最大幸存区S1大小
S1C 当前幸存区S1大小
ECMX    最大eden空间 (KB)
EC  当前eden空间 (KB)
OGCMX   老年代占用的最小空间
OGCMN   老年代占用的最大空间
OGC 当前年老代的容量 (KB)
OC  年老代的空间 (KB)
PGCMN   perm占用的最小空间
PGCMX   perm占用的最大空间
PGC perm空间 (KB)
YGC 年轻代垃圾回收次数
FGC 老年代回收次数
-gcold(统计老年代行为)
 jstat -gcold 4562 
PC  Perm大小
PU  Perm使用大小
MC  方法区大小
MU  方法区使用大小
CCSC    压缩类空间大小
CCSU    压缩类空间使用大小
OC  老年代大小
OU  老年代使用大小
YGC 年轻代垃圾回收次数
FGC 老年代垃圾回收次数
FGCT    老年代垃圾回收消耗时间
GCT 垃圾回收消耗总时间
-gcoldcapacity(老年代与其相应的内存空间的统计)
 jstat -gcoldcapacity 4562 
OGCMN   老年代最小容量
OGCMX   老年代最大容量
OGC 当前年老代的容量 (KB)
OC  当前年老代的空间 (KB)
YGC 年轻代垃圾回收次数
FGC 老年代垃圾回收次数
FGCT    老年代垃圾回收消耗时间
GCT 垃圾回收消耗总时间
-gcpermcapacity(永久代与其相应内存空间的统计)
 jstat -gcnewcapacity 4562 
MCMN    最小元数据容量
MCMX    最大元数据容量
MC  当前元数据空间大小
CCSMN   最小压缩类空间大小
CCSMX   最大压缩类空间大小
CCSC    当前压缩类空间大小
YGC 年轻代垃圾回收次数
FGC 老年代垃圾回收次数
FGCT    老年代垃圾回收消耗时间
GCT 垃圾回收消耗总时间
jinfo

jinfo主要是做jvm当前的java进程的实时参数调整等,这个没有过的解释,用法给大家总结如下:


jinfo.png
jmap

jmap是比较重要的一个工具,因为这个主要是用于当前jvm中的某个java进程的内存dump快照的工具,jamp通常用法就是生成当前的内存快照:
jmap -dump format=b,file="文件路径" pid。具体的用法总结如下:


jmap.png
jstack

jstack主要是分析堆栈的,这个工具也是比较重的,因为,很多的java代码中的线程死锁问题,死循环问题,都可以从这个工具中分析出来!具体用法如下:


jstack.png

OOM案例分析

制造一个oom异常场景
jvm内存配置参数:

-Xms10m -Xmx10m
package com.amazing.util;

import java.util.HashMap;
import java.util.Map;

/**
 * 测试oom异常检测
 */
public class OOMHeap {

    /**
     * oom异常引发原因
     */
    public static void testOom(){
        Map<String,Object> map = new HashMap<>();
        Object [] objetcs = new Object[500000];
        for (int i=0;i<500000;i++){
            map.put("key"+i,String.valueOf(i));
            objetcs[i] = i;
        }

    }

    public static void main(String[] args) {
        testOom();
    }

}

测试结果:


oom异常结果.png

此时,如果你的web应用正在服务器中跑着的时候发生了上述的OOM异常,那么怎么定位,如何下手解决呢?
此时,我们配置这样一个参数:

-XX:+HeapDumpOnOutOfMemoryError  配置oom时的dump快照
-XX:HeapDumpPath=表示生成DUMP文件的路径,也可以指定文件名称

程序加入配置:


dump文件配置.png

此时配置,如果发生OOM异常问题,那么就会为当前的内存问题创建快照,快照的路径在不制定的时候,默认是在当前项目的文件夹下!
测试结果:


测试结果.png
大家可以看出,java进程pid=4148出现了OOM异常,生成了.hprof的内存heap快照,接下来,我们针对这个快照利用工具进行分析!
jvisualvm

这个工具是jdk自带的,分析dump快照的工具,那么此时,我们用它打开我们刚刚创建的快照文件,进行分析!


jvisualvm分析dump文件.png

类内存占用率


jvisualvm类内存占有率.png
那么从这两张图中的检测结果以及我们的程序,我们可以清晰的发现出产生OOM异常引发问题的根源所在,并且能够轻松的排查问题!
那么本篇文章先给大家讲到这里,由于知识点过多的原因,这篇文章没能讲到去实战优化一个正在服务器中运行的项目,那么下一篇再去讲吧!下一篇也是jvm调优的最后一篇实战调优文章了!
上一篇下一篇

猜你喜欢

热点阅读