JVM(六)JVM调优分析的一些命令

一、jps【查看进程id】

  当我们启动了一个web应用程序时,可以通过jps查看其进程id,接着用各种jdk自带命令优化应用。

  使用方式:

二、jmap【查看内存信息,实例个数以及占用内存大小】

查看内存信息

  • num :序号
  • instances :实例数量
  • bytes :占用空间大小
  • class name :类名称
    • [Cchar[]
    • [S :short[]
    • [I :int[]
    • [B :byte[]
    • [[I :int[][]

查看堆信息

JVM生成的dump文件分析

  我们可以在应用程序执行时设置VM参数,让其生成dump文件,用来分析应用的内存使用情况:

三、jstack【查看栈信息,CPU占用情况】

查看栈线程信息

 

  • Thread-1 线程名
  • prio=5 优先级=5
  • os_prio=0 操作系统执行的优先级
  • tid=0x000000001fa9e000 java的线程id
  • nid=0x2d64线程对应的CPU线程标识nid
  • java.lang.Thread.StateBLOCKED 线程状态

四、Jinfo【查看Java系统参数和JVM参数】

查看jvm的参数

查看java系统参数

五、Jstat【查看堆内存各部分的使用量】

  格式:jstat [-命令选项] [vmid] [间隔时间(毫秒)] [查询次数]

垃圾回收统计

  • S0C :第一个幸存区的大小,单位KB
  • S1C :第二个幸存区的大小
  • S0U :第一个幸存区的使用大小
  • S1U :第二个幸存区的使用大小
  • EC :伊甸园区的大小
  • EU :伊甸园区的使用大小
  • OC :老年代大小
  • OU :老年代使用大小
  • MC :方法区大小(元空间)
  • MU :方法区使用大小
  • CCSC :压缩类空间大小
  • CCSU :压缩类空间使用大小
  • YGC :年轻代垃圾回收次数
  • YGCT :年轻代垃圾回收消耗时间,单位s
  • FGC :老年代垃圾回收次数
  • FGCT :老年代垃圾回收消耗时间,单位s
  • GCT :垃圾回收消耗总时间,单位s

新生代垃圾回收统计

  • S0C :第一个幸存区的大小,单位KB
  • S1C :第二个幸存区的大小
  • S0U :第一个幸存区的使用大小
  • S1U :第二个幸存区的使用大小
  • TT :对象在新生代存活的次数
  • MTT :对象在新生代存活的最大次数
  • DSS :期望的幸存区大小
  • EC :伊甸园区的大小
  • EU :伊甸园区的使用大小
  • YGC :年轻代垃圾回收次数
  • YGCT :年轻代垃圾回收消耗时间

老年代垃圾回收统计

  • MC :方法区大小,单位KB
  • MU :方法区使用大小
  • CCSC :压缩类空间大小
  • CCSU :压缩类空间使用大小
  • OC :老年代大小
  • OU :老年代使用大小
  • YGC :年轻代垃圾回收次数
  • FGC :老年代垃圾回收次数
  • FGCT :老年代垃圾回收消耗时间
  • GCT :垃圾回收消耗总时间

堆内存统计

  • NGCMN :新生代最小容量,单位KB
  • NGCMX :新生代最大容量
  • NGC :当前新生代容量
  • S0C :第一个幸存区大小
  • S1C :第二个幸存区的大小
  • EC :伊甸园区的大小
  • OGCMN :老年代最小容量
  • OGCMX :老年代最大容量
  • OGC :当前老年代大小
  • OC :当前老年代大小
  • MCMN :最小元数据容量
  • MCMX :最大元数据容量
  • MC :当前元数据空间大小
  • CCSMN :最小压缩类空间大小
  • CCSMX :最大压缩类空间大小
  • CCSC :当前压缩类空间大小
  • YGC :年轻代gc次数
  • FGC :老年代GC次数

新生代内存统计

  • NGCMN :新生代最小容量,单位KB
  • NGCMX :新生代最大容量
  • NGC :当前新生代容量
  • S0CMX :最大幸存1区大小
  • S0C :当前幸存1区大小
  • S1CMX :最大幸存2区大小
  • S1C :当前幸存2区大小
  • ECMX :最大伊甸园区大小
  • EC :当前伊甸园区大小
  • YGC :年轻代垃圾回收次数
  • FGC :老年代回收次数

老年代内存统计

  • OGCMN :老年代最小容量
  • OGCMX :老年代最大容量
  • OGC :当前老年代大小
  • OC :老年代大小
  • YGC :年轻代垃圾回收次数
  • FGC :老年代垃圾回收次数
  • FGCT :老年代垃圾回收消耗时间
  • GCT :垃圾回收消耗总时间

六、优化思路

  用 jstat gc -pid 命令可以计算出一些关键数据,有了这些数据就可以给自己的系统设置一些初始性的JVM参数,比如堆内存大小,年轻代大小,Eden和Survivor的比例,老年代的大小,大对象的阈值,大龄对象进入老年代的阈值等。

  优化思路:尽量让每次Young GC后的存活对象小于Survivor区域的50%,都留存在年轻代里,尽量别让对象进入老年代。尽量减少Full GC的频率,避免频繁Full GC对JVM性能的影响。

年轻代对象增长的速率

  可以执行命令 jstat -gc pid 1000 10 (每隔1秒执行1次命令,共执行10次),通过观察EU(eden区的使用)来估算每秒eden大概新增多少对象,如果系统负载不高,可以把频率1秒换成1分钟,甚至10分钟来观察整体情况。

  PS:一般系统可能有高峰期和日常期,所以需要在不同的时间分别估算不同情况下对象增长速率。

Young GC的触发频率和每次耗时

  知道年轻代对象增长速率我们就能推根据eden区的大小推算出Young GC大概多久触发一次,Young GC的平均耗时可以通过 YGCT/YGC 公式算出,根据结果我们大概就能知道系统大概多久会因为Young GC的执行而卡顿多久。

每次Young GC后有多少对象存活和进入老年代

  根据上一步的分析已经大概知道Young GC的频率,假设是每5分钟一次,那么可以执行命令 jstat -gc pid 300000 10 ,观察每次结果eden, survivor和老年代使用的变化情况,在每次gc后eden区使用一般会大幅减少,survivor和老年代都有可能增长,这些增长的对象就是每次Young GC后存活的对象,同时还可以看出每次Young GC后进去老年代大概多少对象,从而可以推算出老年代对象增长速率。

Full GC的触发频率和每次耗时

  知道了老年代对象的增长速率就可以推算出Full GC的触发频率了,Full GC的每次耗时可以用公式 FGCT/FGC 计算得出。

七、小问答

Q:突然内存飙升怎么办?

  首先用JVM调优工具看看是不是有大量的类生成了,或者是不是有死循环在暂用资源,还可以用jstack命令来监视,找出占用CPU最高的线程堆栈信息。

Q:如何防止代码中的主动gc影响性能呢?

  线上系统尽量都带上-XX:DisableExplicitGC参数来使得代码内的System.gc()【会造成多余的full gc】这种代码不生效。

原文地址:https://www.cnblogs.com/riches/p/14691816.html