写点什么

叫练手把手教你读 JVM 之 GC 信息

用户头像
叫练
关注
发布于: 2021 年 03 月 15 日
叫练手把手教你读JVM之GC信息

案例


众所周知,GC 主要回收的是堆内存,堆内存中包含年轻代和老年代,年轻代分为 Eden 和 Surivor,如下图所示。我们用案例分析下堆的 GC 信息【版本:HotSpot JDK1.8】。


image.png


/** * @author :jiaolian * @date :Created in 2021-03-15 15:02 * @description:新生代内存测试 * @modified By: * 公众号:叫练 */public class NewGenTest {    public static void main(String[] args) {        //每次在Eden申请1M空间        byte[] bytes = null;        for (int i=0; i<5; i++) {            bytes = new byte[1024*1024];        }    }}
复制代码

案例很简单,for 循环运行 5 次,每次在 Eden 申请 1M 空间,假设我们分配堆内存空间是 20m,并打印 GC 详细信息,配置过程:-XX:+PrintGCDetails -Xmx20m。

  • -XX:+PrintGCDetails:打印 GC 详细信息。

  • -Xmx20m:分配最大堆内存空间是 20m。


GC 详细分析


运行程序,IDEA 控制台打印结果如下:

  1. 第一句话:年轻代 GC 了一次,因为第五次循环,Eden 满了,年轻代内存约 6M(6144K),Eden 回收前约 5M(5057K),回收后是 489K,年轻代内存回收前约是 5M,回收后约是 2M(1783K),总堆内存大小约是 20M(19968K),GC 耗时 0.0016002 secs。

  2. 第二句话:年轻代总内存约 6M,使用约 5M。

  3. 第三句话:eden 空间总内存约 5M(5632K),使用率是 94%。

  4. 第四句话:from 是 512K,使用率是 95%。

  5. 第五句话:老年代总空间约 14M(13824K),使用了 1294K,这个使用空间是因为程序在 Eden 申请 1M 空间,判断空间不够,就申请 from 或者 to 空间,发现只有 512K,就触发 monitor GC,将 1M 内存申请在老年代。

  6. 第六句话:元空间内存。


image.png


  • -Xms 初始堆大小,不够时,会自动扩展,所以一般 Xms 空间和 Xmx 最大堆空间设置成一样的。

上面程序不变,设置 JVM 参数,-XX:+PrintGCDetails -Xmx20m -Xms5m,运行程序,部分结果如下图所示。


image.png


如上图所示:初始化堆大小是 5M,新生代内存一共发生了 4 次 GC,从上图可以分析,Eden 只有 1M 多内存可以被申请,所以第二次 for 循环申请 1M 空间就触发了 GC,数据就被丢进老年代,连续 3 次后,GC 堆的空间由 5M 变为了 6M,说明初始化堆空间不够使,可以自动扩展堆内存。


当然我们还可以通过-Xmn 设置年轻代大小。下面我们看看年轻代中,Eden 和 from/to 区域怎么划分。

上面程序不变,设置 JVM 参数,-XX:+PrintGCDetails -Xmx20m -Xmn10m -XX:SurvivorRatio=2,运行程序,部分结果如下图所示。

  • -Xmn10m:设置新生代内存为 10m

  • -XX:SurvivorRatio=2:设置新生代中 eden 和 Survivor 比例是 2:1


image.png


我们设置新生代是 10M,这里显示新生代大小是 7.5M(7680K),实际上 from/to 是有一块空间是每次 GC 做交换的区域(方便垃圾回收),所以实际上 7680K=5120+2560。5120/2560=2,也就是新生代和和 Survivor 空间比例。


另外还有:-XX:NewRatio:设置老年代和新生代比例,一般是 1/3)。比如设置-XX:NewRatio=2 -XX:+PrintGCDetails -Xmx30m

那么老年代空间是 20M,新生代空间是 10M。


总结


最后总结下:

  • -XX:+PrintGCDetails:打印 GC 详细信息。

  • -Xmx20m:分配最大堆内存空间是 20m。

  • -Xmn10m:设置新生代内存为 10m

  • -XX:SurvivorRatio=2:设置新生代中 eden 和 Survivor 比例。

  • -XX:NewRatio:设置老年代和新生代比例,一般是 1/3)。

今天学习了 JVM 之 GC 信息参数配置,写的不全同时还有许多需要修正的地方,希望亲们加以指正和点评,喜欢的请点赞加关注哦。点关注,不迷路,我是叫练公众号,微信号【jiaolian123abc】边叫边练。


发布于: 2021 年 03 月 15 日阅读数: 6
用户头像

叫练

关注

我是叫练,边叫边练 2020.06.11 加入

Java高级工程师,熟悉多线程,JVM

评论

发布
暂无评论
叫练手把手教你读JVM之GC信息