jstat 查看监控 Heap size和JVM垃圾回收情况

当 Java 程序有性能问题时 , 尤其是响应时间有突然变化时 , 最好第一时间查看 GC 的状态 。 一般用 jstat -gcutil1s 来查看 , 那么它的输出又是什么含义呢?
一般会用两种方式调用 jstat, 一种看百分比 , 一种看具体数值(KB) 。
在开始使用jstat命令之前 , 先简单了解一下JVM内存区域 , 以及Minor GC和Major GC的概念 。
一、JVM内存区域概览JVM区域总体分两类 , Heap区和非Heap区 。
Heap区又分为:年轻代(Young Generation)和老年代(Old Generation) 。
jstat 查看监控 Heap size和JVM垃圾回收情况文章插图
年轻代是所有新对象产生的地方 。 当年轻代内存空间被用完时 , 就会触发垃圾回收 。 这个垃圾回收叫做Minor GC 。
年轻代被分为3个部分—Eden区和两个Survivor区 。
老年代内存里包含了长期存活的对象和经过多次Minor GC后依然存活下来的对象 , 通常会在老年代内存被占满时进行垃圾回收 。 老年代的垃圾收集叫做Major GC , Major GC通常是跟full GC是等价的 , 收集整个GC堆 。

  • Eden Space(伊甸园);
  • Survivor Space(2个幸存者区);
  • Old Gen(老年代);
非Heap区又分:
  • Code Cache(代码缓存区);
  • Perm Gen(永久代);JDK1.8之后被元空间替代;Perm Gen全称是Permanent Generation space , 称之为永久代 , 其实指的就是这个方法区 。
  • Jvm Stack(java虚拟机栈);
  • Local Method Statck(本地方法栈);

jstat 查看监控 Heap size和JVM垃圾回收情况文章插图
二、Minor GC和Major GC新生代 GC(Minor GC):指发生在新生代的垃圾收集动作 , 因为 Java 对象大多都具备朝生夕灭的特性 , 所以 Minor GC 非常频繁 , 一般回收速度也比较快 。
老年代 GC(Major GC/Full GC):指发生在老年代的 GC , 出现了 Major GC , 经常会伴随至少一次的 Minor GC(但非绝对的 , 在 ParallelScavenge 收集器的收集策略里就有直接进行 Major GC 的策略选择过程) 。 Major GC 的速度一般会比 Minor GC 慢 10
倍以上 。
其中Minor GC如下图所示:
jstat 查看监控 Heap size和JVM垃圾回收情况文章插图
在GC开始的时候 , 对象只会存在于Eden区和名为“From”的Survivor区 , Survivor区“To”是空的 。 紧接着进行GC , Eden区中所有存活的对象都会被复制到“To” , 而在“From”区中 , 仍存活的对象会根据他们的年龄值来决定去向 。 年龄达到一定值(年龄阈值 , 可以通过-XX:MaxTenuringThreshold来设置)的对象会被移动到年老代中 , 没有达到阈值的对象会被复制到“To”区域 。 经过这次GC后 , Eden区和From区已经被清空 。
jstat 查看监控 Heap size和JVM垃圾回收情况文章插图
这个时候 , “From”和“To”会交换他们的角色 , 也就是新的“To”就是上次GC前的“From” , 新的“From”就是上次GC前的“To” 。 不管怎样 , 都会保证名为To的Survivor区域是空的 。 Minor GC会一直重复这样的过程 , 直到“To”区被填满 , “To”区被填满之后 , 会将所有对象移动到年老代中 。
jstat 查看监控 Heap size和JVM垃圾回收情况文章插图
Major GC 和 Full GC
  • Major GC 是清理老年代 。
  • Full GC 是清理整个堆空间—包括年轻代和老年代 。
Major GC很具有代表性 , Major GC次数和时间指标很能显示系统性能问题 。 如果这两个指标很大 , 很大程度上说明了程序中有问题 , 垃圾一直回收不掉 。
jstat 查看监控 Heap size和JVM垃圾回收情况文章插图
三、查看监控Heap size 和 JVM 垃圾回收情况尤其是GC情况的监控 , 如果老年代发生Full GC , 那么很可能会导致内存泄漏的可能性 。
jstat -gcutil PID
jstat 查看监控 Heap size和JVM垃圾回收情况文章插图
jstat -gcutil PID 1s
会每隔一秒输出内存相关信息 , 示例输出如下:
jstat 查看监控 Heap size和JVM垃圾回收情况文章插图
输出列内容说明:
S0: Survivor 0区的空间使用率 Survivor space 0 utilization as a percentage of the space's current capacity.
S1: Survivor 1区的空间使用率 Survivor space 1 utilization as a percentage of the space's current capacity.
E: Eden区的空间使用率 Eden space utilization as a percentage of the space's current capacity.
O: 老年代的空间使用率 Old space utilization as a percentage of the space's current capacity.
M: 元数据的空间使用率 Metaspace utilization as a percentage of the space's current capacity.