20240220

2024/2/20

# jvm调试

找到jdk安装路径

运行一个不终止程序

运行jvisulvm.exe

# 参数说明

# space区

  • Metaspace:方法区,如果JDK1.8之前的版本,就是Perm,JDK7和之前的版本都是以永久代- (PermGen)来实现方法区的,JDK8之后改用元空间来实现(MetaSpace)。
  • Old:老年代
  • Eden: 新生代Eden区
  • S0和S1:新生代的两个 Survivor 区

# Graphs区域

  • Compile Time:编译情况 5794 compoles - 11.682s 表示编译总数为5794 ,编译总耗时为11.682s。 一个脉冲表示一次JIT编译,脉冲越宽表示编译时间越长。
  • Class Loader Time:类加载情况 9480 loaded,0 unloaded - 5.561s表示已加载的数量为9480 ,卸载的数量为0,耗时为5.561s。
  • GC Time:总的(包含新生代和老年代)gc情况记录 16 collections,140.800ms Last Cause:G1 Evacuation Pause表示一共经历了16次gc(包含Minor GC和Full GC),总共耗时140.800。最后一次GC原因G1 Evacuation Pause
  • Eden Space:新生代Eden区内存使用情况 (1.000G,44.000M): 27.000M,14 collections,75.425ms表示Eden区的最大容量为1G,当前初始值容量为44.000M,当前已使用27.000M,从开始监控到现在在该内存区域一共发生了14次gc(Minor GC),gc总耗时为75.425ms。 Eden区的最大容量是我们设置的最大堆内存,程序运行时如果超过该值就会发生内存移除错误,当前初始值容量是根据当前使用堆内存的情况动态调整,如果使用堆内存呈上升趋势,那么初始值也会上升,知道最大值。反之下降。
  • Survivor 0和Survivor 1:新生代的两个Survivor区内存使用情况 (1.000G,1.000M):1.000M表示该Survivor区的最大容量为1G(默认为Eden区的1/8),当前已用1.000M。
  • Old Gen:老年代内存使用情况 (1.000M,83.000M):57.172M,2 collections,65.375ms表示老年区的最大容量为1G,当前容量为83.000M,当前已用57.172M,从开始监控到现在在该内存区域一共发生了2次gc(Full GC),gc总耗时为65.375ms,换算下可以看出单次Full GC要比Minor GC耗时长很多。
  • Metaspace:方法区内存使用情况 (1.045G,54.613M):53.482M表示方法区最大容量为1.045G,当前容量为54.613M,当前使用量为53.482M。

# Histogram区域

  • Tenuring Threshold:我们知道Survivor区中的对象有一套晋升机制,就是其中的每个对象都有一个年龄标记,每当对象在一次Minor GC中存活下来,其年龄就会+1,当对象的年龄大于一个阈值时,就会进入老年代,这个阈值就是Tenuring Threshold,要注意这个值不是固定不变的,一般情况下Tenuring Threshold会与Max Tenuring Threshold大小保持一致,可如果某个时刻Survivor区中相同年龄的所有对象的内存总等于Survivor空间的一半,那Tenuring Threshold就会等于该年龄,同时大于或等于该年龄的所有对象将进入老年代。
  • Max Tenuring Threshold:表示新生代中对象的最大年龄值,这个值在JDK1.8中默认为6,在JDK1.7及之前的版本中默认为15,可以通过参数-XX:MaxTenuringThreshold来指定。
  • Desired Survivor Size:Survivor空间大小验证阈值(默认是survivor空间的一半),用于给Tenuring Threshold判断对象是否提前进入老年代。
  • Current Survivor Size:当前Survivor空间大小,单位为字节(Byte,B)
  • Histogram柱状图:表示Survivor中不同年龄段对象分布。

# 小灿白话