ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

JVM-GC日志详细分析

2021-11-21 21:30:19  阅读:216  来源: 互联网

标签:used space 0.00 XX gc JVM GC 详细分析


JVM-GC日志详细分析

1.打印GC日志参数

1.3 基本JVM参数
参数示例描述说明
-verbose:gc控制台打印GC参数
-Xms20M初始堆大小 20M
-Xmx20M最大堆大小20M 一般情况下-Xms和-Xmx这两个值设为相同大小
-Xmn10M新生代最大可用值10M
-XX:+PrintGC触发GC时日志打印
-XX:+PrintGCDetails触发GC时日志打印详细
–XX:UseSerialGC串行回收
-XX:SurvivorRatio=8eden:from:to =8:1:1
-XX:+HeapDumpOnOutOfMemoryErroOOM时生成Dump文件
-XX:NewRatio=2新生代:老年代 = 1:2

2.GC日志分析

2.1首先运行程序,打印GC参数及日志

设置JVM运行参数

-verbose:gc -Xms20M -Xmx20M  -Xmn10M -XX:+PrintGC -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError -XX:SurvivorRatio=8

运行程序

package com.jzj.jvmtest.gctest;

/**
 * 分析gc日志 主动通过 system.gc触发 垃圾回收
 * 设置 -verbose:gc -Xms20M -Xmx20M -Xmn10M  -XX:+PrintGC -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError  -XX:SurvivorRatio=8
 */
public class SystemGcLog {

    private static final int ONE_MB = 1024 * 1024;

    /**
     * 设置内存20M,最大堆内存20M,新生代10M,那么就剩余10M给老年代
     * 新生代 10M ,Eden:survivor = 8:1, 所以 Eden: 8M, fromSurvivor:1M, toSurvivor:1M, 新生代可用空间就是 8+1 9M
     *
     * @param args
     */
    public static void main(String[] args) {
        //定义1个 byte
        byte[] allocation = new byte[ONE_MB];
        //将 allocation 置为空, 让他成为 垃圾
        allocation = null;
        //主动调用 system.gc() 统计垃圾处理器 回收垃圾
        System.gc();
    }
}

3.分析GC日志

[GC (System.gc()) [PSYoungGen: 3704K->1000K(9216K)] 3704K->1042K(19456K), 0.0010446 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[Full GC (System.gc()) [PSYoungGen: 1000K->0K(9216K)] [ParOldGen: 42K->819K(10240K)] 1042K->819K(19456K), [Metaspace: 3399K->3399K(1056768K)], 0.0034435 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
Heap
 PSYoungGen      total 9216K, used 246K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)
  eden space 8192K, 3% used [0x00000000ff600000,0x00000000ff63d890,0x00000000ffe00000)
  from space 1024K, 0% used [0x00000000ffe00000,0x00000000ffe00000,0x00000000fff00000)
  to   space 1024K, 0% used [0x00000000fff00000,0x00000000fff00000,0x0000000100000000)
 ParOldGen       total 10240K, used 819K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)
  object space 10240K, 7% used [0x00000000fec00000,0x00000000fecccc28,0x00000000ff600000)
 Metaspace       used 3406K, capacity 4496K, committed 4864K, reserved 1056768K
  class space    used 376K, capacity 388K, committed 512K, reserved 1048576K

Process finished with exit code 0
3.1 GC日志的分析
[GC (System.gc()) [PSYoungGen: 3704K->1000K(9216K)] 3704K->1042K(19456K), 0.0010446 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC的类别] =》 [gc发生区域]
[PSYoungGen: 3704K->1000K(9216K)] =》 3704K gc发生前,该区域使用的容量,->1000K, gc发生后,该区域使用的容量,(9216K)当前区域的总容量]
外层的3704K->1042K(19456K) =》  3704K->1042K(19456K) 3704K gc前 堆使用的大小, ->1042K gc后,堆使用的容量,19456是堆空间的总容量 
[Times: user=0.00 sys=0.00, real=0.00 secs] =》 user:用户态消耗CPU时间,sys系统内核消耗CPU时间,real从开始到结束使用的时钟时间
  1. GC (System.gc() ) 局部收集 新生代 的模式
    Young GC: 只收集young gen的GC,Young GC还有种说法就叫做 “Minor GC”
    Old GC: 只收集old gen的GC。只有垃圾收集器CMS的concurrent collection 是这个模式
    Mixed GC: 收集整个young gen 以及部分old gen的GC。只有垃圾收集器 G1有这个模式

  2. Full GC 就是收集整个堆,包括新生代,老年代,永久代(在JDK 1.8及以后,永久代会被移除,换为metaspace(元空间))等收集所有部分的模式。

不同的垃圾收集器,触发条件可能不一样

  • 当准备要触发一次 young GC时,如果发现统计数据说之前 young GC的平均大小比目前的 old gen剩余的空间大,则不会触发young GC而是转为触发 full GC (因为HotSpot VM的GC里,除了垃圾回收器 CMS的concurrent collection 之外,其他能收集old gen的GC都会同时收集整个GC堆,包括young gen,所以不需要事先准备一次单独的young GC)
  • 如果有永久代(perm gen) ,要在永久代分配空间但已经没有足够空间时,也要触发一次 full GC
  • 执行System.gc(),heap dump带GC, 其默认都是触发 full GC
  1. PSYoungGen/ParOldGen 表示GC发生的区域, 我们的JVM是哦用的是Server模式,默认的垃圾收集器组合就是Parallel Scavenge垃圾收集器的新生代和使用Parallel old垃圾收集器的老生代在这里插入图片描述
  2. [PSYoungGen: 3704K->1000K(9216K)] =》 3704K gc发生前,该区域使用的容量,->1000K, gc发生后,该区域使用的容量,(9216K)当前区域的总容量]
  3. 外层的3704K->1042K(19456K) =》 3704K->1042K(19456K) 3704K gc前 堆使用的大小, ->1042K gc后,堆使用的容量,19456是堆空间的总容量
  4. [Times: user=0.00 sys=0.00, real=0.00 secs] =》 user:用户态消耗CPU时间,sys系统内核消耗CPU时间,real从开始到结束使用的时钟时间
3.2 GC 堆日志的分析

可以看到堆的 日志如下

Heap
 PSYoungGen      total 9216K, used 246K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)
  eden space 8192K, 3% used [0x00000000ff600000,0x00000000ff63d890,0x00000000ffe00000)
  from space 1024K, 0% used [0x00000000ffe00000,0x00000000ffe00000,0x00000000fff00000)
  to   space 1024K, 0% used [0x00000000fff00000,0x00000000fff00000,0x0000000100000000)
 ParOldGen       total 10240K, used 819K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)
  object space 10240K, 7% used [0x00000000fec00000,0x00000000fecccc28,0x00000000ff600000)
 Metaspace       used 3406K, capacity 4496K, committed 4864K, reserved 1056768K
  class space    used 376K, capacity 388K, committed 512K, reserved 1048576K
  1. PSYoungGen total 9216K, used 246K 堆中 新生代大小,一共9216K也就是9m,9M怎么来的?JVM参数设置的 -Xmn10M,设置的-XX:SurvivorRatio=8 说明 Eden:From:To分别是8:1:1,这样 一共10M的新生代, From和To 只有一块可以用, 所以可使用的内存就是 8+1=9M, 现在用了 246K
  2. eden space 8192K, 3% used Eden区域用了8M
  3. from space 1024K, 0% used to space 1024K, 0% From Survivor和To Survivor都是1M
  4. ParOldGen total 10240K, used 819K 老年代一共10M, 10M怎么来的呢? 设置的 -Xms20M, 堆最大内存20M,其中 -Xmn10M用了10M,那么 老年代就剩余10M了, used 819k,使用了819KB
  5. Metaspace used 3437K, capacity 4496K, committed 4864K, reserved 1056768K

详细看下 Metaspace 细分这么多是干什么的

其中used和capacity是从类加载器的角度来衡量的
而committed和reserved是从操作系统地址空间的角度来衡量

  1. used:是分配给所有类加载器的metachunk中用来存储元数据的部分的大小
  2. capacity:分配给所有类加载器的metachunk的大小,包含每个metachunk的head、used、wasted和current metachunk的free部分
  3. committed:向OS申请的内存中已经分配物理内存的大小,包含VirtualSpaceList中所有node已经commit的部分(也就是非当前node+当前node commit的部分),或者说所有类加载器的capacity+全局空闲链表Chunk Manager+硬件预留HWM margin
  4. reserved:JVM进程虚拟地址空间的部分,像class metaspace默认CompressedClassSpaceSize是1GB,所以reserved就是1GB,日志中的metaspace包含class space和no-class space。
3.2 GC Metaspace元空间分析

JDK 1.7和 JDK 1.8 中,会出现堆内存溢出,并且 JDK 1.8中 PermSize 和 MaxPermGen 已经无效。因此,可以大致验证 JDK 1.7 和 1.8 将字符串常量由永久代转移到堆中,并且 JDK 1.8 中已经不存在永久代的结论。

元空间的本质和永久代类似,都是对JVM规范中方法区的实现。不过元空间与永久代之间最大的区别在于:元空间并不在虚拟机中,而是使用本地内存。因此,默认情况下,元空间的大小仅受本地内存限制,但可以通过以下参数来指定元空间的大小:

-XX:MetaspaceSize,初始空间大小,达到该值就会触发垃圾收集进行类型卸载,同时GC会对该值进行调整:如果释放了大量的空间,就适当降低该值;如果释放了很少的空间,那么在不超过MaxMetaspaceSize时,适当提高该值。
  -XX:MaxMetaspaceSize,最大空间,默认是没有限制的。

除了上面两个指定大小的选项以外,还有两个与 GC 相关的属性:
  -XX:MinMetaspaceFreeRatio,在GC之后,最小的Metaspace剩余空间容量的百分比,减少为分配空间所导致的垃圾收集
  -XX:MaxMetaspaceFreeRatio,在GC之后,最大的Metaspace剩余空间容量的百分比,减少为释放空间所导致的垃圾收集

标签:used,space,0.00,XX,gc,JVM,GC,详细分析
来源: https://blog.csdn.net/u010134642/article/details/121459397

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有