JDK1.8 MinorGC年轻代数据直接进入老年代案例分析

1 篇文章 0 订阅

一次MinorGC案例研究时,一个M对象进入年轻代时,发现年轻代无法放下该对象,于是触发MinorGC,之后年轻代内的数据全部进入了老年代,M对象才得以进入年轻代;

JDK版本:java version "1.8.0_191"

JVM参数:-XX:+UseSerialGC -Xmx20m -Xms20m -Xmn10m -XX:+PrintGCDetails -XX:MaxTenuringThreshold=15

代码如下:

package com.study.demo.gc;

public class MinorGC3 {

    private static final int _1MB = 1024 * 1024;

    //MaxTenuringThreshold分代年龄1到15
    //-XX:+UseSerialGC -Xmx20m -Xms20m -Xmn10m -XX:+PrintGCDetails -XX:MaxTenuringThreshold=15
    public static void main(String[] args) {
        byte[] allocation1, allocation2, allocation3;
        allocation1 = new byte[_1MB / 4];
        allocation2 = new byte[4 * _1MB];
        allocation3 = new byte[4 * _1MB];
        allocation3 = null;
        allocation3 = new byte[6 * _1MB];
    }
}

运行结果 :

C:\Java\jdk1.8.0_191\bin\java.exe -XX:+UseSerialGC -Xmx20m -Xms20m -Xmn10m -XX:+PrintGCDetails -XX:MaxTenuringThreshold=15 "-javaagent:D:\idea\IntelliJ IDEA 2018.1.6\lib\idea_rt.jar=62091:D:\idea\IntelliJ IDEA 2018.1.6\bin" -Dfile.encoding=UTF-8 -classpath C:\Java\jdk1.8.0_191\jre\lib\charsets.jar;C:\Java\jdk1.8.0_191\jre\lib\deploy.jar;C:\Java\jdk1.8.0_191\jre\lib\ext\access-bridge-64.jar;C:\Java\jdk1.8.0_191\jre\lib\ext\cldrdata.jar;C:\Java\jdk1.8.0_191\jre\lib\ext\dnsns.jar;C:\Java\jdk1.8.0_191\jre\lib\ext\jaccess.jar;C:\Java\jdk1.8.0_191\jre\lib\ext\jfxrt.jar;C:\Java\jdk1.8.0_191\jre\lib\ext\localedata.jar;C:\Java\jdk1.8.0_191\jre\lib\ext\nashorn.jar;C:\Java\jdk1.8.0_191\jre\lib\ext\sunec.jar;C:\Java\jdk1.8.0_191\jre\lib\ext\sunjce_provider.jar;C:\Java\jdk1.8.0_191\jre\lib\ext\sunmscapi.jar;C:\Java\jdk1.8.0_191\jre\lib\ext\sunpkcs11.jar;C:\Java\jdk1.8.0_191\jre\lib\ext\zipfs.jar;C:\Java\jdk1.8.0_191\jre\lib\javaws.jar;C:\Java\jdk1.8.0_191\jre\lib\jce.jar;C:\Java\jdk1.8.0_191\jre\lib\jfr.jar;C:\Java\jdk1.8.0_191\jre\lib\jfxswt.jar;C:\Java\jdk1.8.0_191\jre\lib\jsse.jar;C:\Java\jdk1.8.0_191\jre\lib\management-agent.jar;C:\Java\jdk1.8.0_191\jre\lib\plugin.jar;C:\Java\jdk1.8.0_191\jre\lib\resources.jar;C:\Java\jdk1.8.0_191\jre\lib\rt.jar;E:\idea_work_study\jvm_study\target\classes;E:\m2\cglib\cglib\2.2.2\cglib-2.2.2.jar;E:\m2\asm\asm\3.3.1\asm-3.3.1.jar com.study.demo.gc.MinorGC3
[GC (Allocation Failure) [DefNew: 5842K->845K(9216K), 0.0024170 secs] 5842K->4941K(19456K), 0.0024415 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC (Allocation Failure) [DefNew: 5023K->0K(9216K), 0.0008570 secs] 9119K->4937K(19456K), 0.0008703 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
Heap
 def new generation   total 9216K, used 6364K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)
  eden space 8192K,  77% used [0x00000000fec00000, 0x00000000ff236e08, 0x00000000ff400000)
  from space 1024K,   0% used [0x00000000ff400000, 0x00000000ff400388, 0x00000000ff500000)
  to   space 1024K,   0% used [0x00000000ff500000, 0x00000000ff500000, 0x00000000ff600000)
 tenured generation   total 10240K, used 4936K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)
   the space 10240K,  48% used [0x00000000ff600000, 0x00000000ffad2088, 0x00000000ffad2200, 0x0000000100000000)
 Metaspace       used 3104K, capacity 4496K, committed 4864K, reserved 1056768K
  class space    used 337K, capacity 388K, committed 512K, reserved 1048576K

Process finished with exit code 0

分析:年轻代10M 能用的只有9M 老年代10M

1.allocation1 = new byte[_1MB / 4];   256kb数据进入年轻代
2.allocation2 = new byte[4 * _1MB];   4Mb数据进入年轻代
3.allocation3 = new byte[4 * _1MB];   4Mb数据准备进入年轻代时,年轻代发现放不下,先MinorGC,发现4MB+256KB进入不了Survivor的from或者to区(from/to只有1MB),于是通过担保策略,将年轻代的数据全部放入老年代也就是4MB+256Kb的数据进入了老年代,这时候4MB的数据就可以进到年轻代了
4.allocation3 = new byte[6 * _1MB];   6MB的数据准备进入年轻代,年轻代发现放不下,先MinorGC,清理原先的4MB,由于allocation3 = null,6MB的数据就能进来了。
总共两次MinorGC

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值