Java 虚拟机

【Java 虚拟机笔记】内存分配策略相关整理

2019-02-27  本文已影响22人  58bc06151329

文前说明

作为码农中的一员,需要不断的学习,我工作之余将一些分析总结和学习笔记写成博客与大家一起交流,也希望采用这种方式记录自己的学习之旅。

本文仅供学习交流使用,侵权必删。
不用于商业目的,转载请注明出处。

1. 概述

Minor GC

Major GC / Full GC

HotSpot 虚拟机 GC 的过程

初始阶段 Eden 区满 使用标记-复制将对象复制到 S0 再一次 Minor GC 再一次 MinorGC 从新生代 Promotion 到老年代 不断会有新的对象被 Promote 到老年代 Major GC 将会在老年代发生

2. 对象优先在 Eden 分配

/**
 * -XX:+UseSerialGC -XX:+PrintGCDetails -verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:SurvivorRatio=8
 */
public class Test {

    private static final int _1MB = 1024 * 1024;

    public static void main(String[] args) {

        byte[] allocation1, allocation2, allocation3, allocation4;

        allocation1 = new byte[2 * _1MB];
        allocation2 = new byte[2 * _1MB];
        allocation3 = new byte[2 * _1MB];
        allocation4 = new byte[4 * _1MB];
    }
}
//[GC (Allocation Failure) [DefNew: 7307K->375K(9216K), 0.0023729 secs] 7307K->6519K(19456K), 0.0024046 secs] [Times: user=0.01 sys=0.00, real=0.01 secs] 
//Heap
// def new generation   total 9216K, used 4635K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)
//  eden space 8192K,  52% used [0x00000000fec00000, 0x00000000ff029140, 0x00000000ff400000)
//  from space 1024K,  36% used [0x00000000ff500000, 0x00000000ff55dd40, 0x00000000ff600000)
//  to   space 1024K,   0% used [0x00000000ff400000, 0x00000000ff400000, 0x00000000ff500000)
// tenured generation   total 10240K, used 6144K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)
//   the space 10240K,  60% used [0x00000000ff600000, 0x00000000ffc00030, 0x00000000ffc00200, 0x0000000100000000)
// Metaspace       used 3357K, capacity 4494K, committed 4864K, reserved 1056768K
//  class space    used 325K, capacity 386K, committed 512K, reserved 1048576K

3. 大对象直接进入老年代

/**
 * -XX:+UseSerialGC -XX:+PrintGCDetails -verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:SurvivorRatio=8
 */
public class Test {

    private static final int _1MB = 1024 * 1024;

    public static void main(String[] args) {

        byte[] allocation1;
        allocation1 = new byte[4 * _1MB];
    }
}
//Heap
// def new generation   total 9216K, used 5423K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)
//  eden space 8192K,  66% used [0x00000000fec00000, 0x00000000ff14bf48, 0x00000000ff400000)
//  from space 1024K,   0% used [0x00000000ff400000, 0x00000000ff400000, 0x00000000ff500000)
//  to   space 1024K,   0% used [0x00000000ff500000, 0x00000000ff500000, 0x00000000ff600000)
// tenured generation   total 10240K, used 0K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)
//   the space 10240K,   0% used [0x00000000ff600000, 0x00000000ff600000, 0x00000000ff600200, 0x0000000100000000)
// Metaspace       used 3340K, capacity 4494K, committed 4864K, reserved 1056768K
//  class space    used 322K, capacity 386K, committed 512K, reserved 1048576K

//-XX:PretenureSizeThreshold=3145728
//Heap
// def new generation   total 9216K, used 1327K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)
//  eden space 8192K,  16% used [0x00000000fec00000, 0x00000000fed4bf38, 0x00000000ff400000)
//  from space 1024K,   0% used [0x00000000ff400000, 0x00000000ff400000, 0x00000000ff500000)
//  to   space 1024K,   0% used [0x00000000ff500000, 0x00000000ff500000, 0x00000000ff600000)
// tenured generation   total 10240K, used 4096K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)
//   the space 10240K,  40% used [0x00000000ff600000, 0x00000000ffa00010, 0x00000000ffa00200, 0x0000000100000000)
// Metaspace       used 3333K, capacity 4494K, committed 4864K, reserved 1056768K
//  class space    used 319K, capacity 386K, committed 512K, reserved 1048576K

4. 长期存活的对象将进入老年代

/**
 * -XX:+UseSerialGC -XX:+PrintGCDetails -verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:SurvivorRatio=8
 */
public class Test {

    private static final int _1MB = 1024 * 1024;

    public static void main(String[] args) {

        byte[] allocation1, allocation2, allocation3;

        allocation1 = new byte[1 * _1MB / 4];
        allocation2 = new byte[4 * _1MB];
        allocation3 = new byte[4 * _1MB];// 第一次 Minor GC
        allocation3 = null;
        allocation3 = new byte[4 * _1MB];// 第二次 Minor GC
    }
}
//-XX:MaxTenuringThreshold=15
//[GC [DefNew: 5463K->456K(9216K), 0.0053475 secs] 5463K->4552K(19456K), 0.0053895 secs] [Times: user=0.02 sys=0.00, real=0.00 secs] 
//[GC [DefNew: 4964K->456K(9216K), 0.0010450 secs] 9060K->4552K(19456K), 0.0010711 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
//Heap
// def new generation   total 9216K, used 4775K [0x00000000f9a00000, 0x00000000fa400000, 0x00000000fa400000)
//  eden space 8192K,  52% used [0x00000000f9a00000, 0x00000000f9e37be0, 0x00000000fa200000)
//  from space 1024K,  44% used [0x00000000fa200000, 0x00000000fa272170, 0x00000000fa300000)
//  to   space 1024K,   0% used [0x00000000fa300000, 0x00000000fa300000, 0x00000000fa400000)
// tenured generation   total 10240K, used 4096K [0x00000000fa400000, 0x00000000fae00000, 0x00000000fae00000)
//   the space 10240K,  40% used [0x00000000fa400000, 0x00000000fa800010, 0x00000000fa800200, 0x00000000fae00000)
// compacting perm gen  total 21248K, used 3497K [0x00000000fae00000, 0x00000000fc2c0000, 0x0000000100000000)
//   the space 21248K,  16% used [0x00000000fae00000, 0x00000000fb16ab58, 0x00000000fb16ac00, 0x00000000fc2c0000)

//-XX:MaxTenuringThreshold=1
//[GC [DefNew: 5463K->458K(9216K), 0.0038139 secs] 5463K->4554K(19456K), 0.0038559 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
//[GC [DefNew: 4967K->0K(9216K), 0.0007399 secs] 9063K->4554K(19456K), 0.0007592 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
//Heap
// def new generation   total 9216K, used 4234K [0x00000000f9a00000, 0x00000000fa400000, 0x00000000fa400000)
//  eden space 8192K,  51% used [0x00000000f9a00000, 0x00000000f9e227f0, 0x00000000fa200000)
//  from space 1024K,   0% used [0x00000000fa200000, 0x00000000fa2001e0, 0x00000000fa300000)
//  to   space 1024K,   0% used [0x00000000fa300000, 0x00000000fa300000, 0x00000000fa400000)
// tenured generation   total 10240K, used 4554K [0x00000000fa400000, 0x00000000fae00000, 0x00000000fae00000)
//   the space 10240K,  44% used [0x00000000fa400000, 0x00000000fa8729a8, 0x00000000fa872a00, 0x00000000fae00000)
// compacting perm gen  total 21248K, used 3598K [0x00000000fae00000, 0x00000000fc2c0000, 0x0000000100000000)
//   the space 21248K,  16% used [0x00000000fae00000, 0x00000000fb1840b0, 0x00000000fb184200, 0x00000000fc2c0000)

5. 动态对象年龄判定

/**
 * -XX:+UseSerialGC -XX:+PrintGCDetails -verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:SurvivorRatio=8
 */
public class Test {
    private static final int _1MB = 1024 * 1024;

    public static void main(String[] args) {

        byte[] allocation1, allocation2, allocation3, allocation4;

        allocation1 = new byte[1 * _1MB / 4];
        allocation2 = new byte[2 * _1MB / 4];//注释前后对比(不注释,则 allocation1 + allocation2 大于 Survivor 空间的一半)
        allocation3 = new byte[4 * _1MB];
        allocation4 = new byte[4 * _1MB];// 第一次 Minor GC
        allocation4 = new byte[4 * _1MB];// 第二次 Minor GC
    }
}
//allocation2 被注释的情况下
//[GC [DefNew: 5463K->456K(9216K), 0.0040297 secs] 5463K->4552K(19456K), 0.0040705 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
//[GC [DefNew: 4964K->456K(9216K), 0.0035523 secs] 9060K->8648K(19456K), 0.0035859 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
//Heap
// def new generation   total 9216K, used 4690K [0x00000000f9a00000, 0x00000000fa400000, 0x00000000fa400000)
//  eden space 8192K,  51% used [0x00000000f9a00000, 0x00000000f9e227e8, 0x00000000fa200000)
//  from space 1024K,  44% used [0x00000000fa200000, 0x00000000fa2721b8, 0x00000000fa300000)
//  to   space 1024K,   0% used [0x00000000fa300000, 0x00000000fa300000, 0x00000000fa400000)
// tenured generation   total 10240K, used 8192K [0x00000000fa400000, 0x00000000fae00000, 0x00000000fae00000)
//   the space 10240K,  80% used [0x00000000fa400000, 0x00000000fac00020, 0x00000000fac00200, 0x00000000fae00000)
// compacting perm gen  total 21248K, used 3507K [0x00000000fae00000, 0x00000000fc2c0000, 0x0000000100000000)
//   the space 21248K,  16% used [0x00000000fae00000, 0x00000000fb16ce88, 0x00000000fb16d000, 0x00000000fc2c0000)

//allocation2 没有注释的情况下
//[GC [DefNew: 5975K->968K(9216K), 0.0042617 secs] 5975K->5064K(19456K), 0.0043078 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
//[GC [DefNew: 5476K->0K(9216K), 0.0030553 secs] 9572K->9160K(19456K), 0.0030796 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
//Heap
// def new generation   total 9216K, used 4234K [0x00000000f9a00000, 0x00000000fa400000, 0x00000000fa400000)
//  eden space 8192K,  51% used [0x00000000f9a00000, 0x00000000f9e22750, 0x00000000fa200000)
//  from space 1024K,   0% used [0x00000000fa200000, 0x00000000fa200330, 0x00000000fa300000)
//  to   space 1024K,   0% used [0x00000000fa300000, 0x00000000fa300000, 0x00000000fa400000)
// tenured generation   total 10240K, used 9159K [0x00000000fa400000, 0x00000000fae00000, 0x00000000fae00000)
//   the space 10240K,  89% used [0x00000000fa400000, 0x00000000facf1f20, 0x00000000facf2000, 0x00000000fae00000)
// compacting perm gen  total 21248K, used 3524K [0x00000000fae00000, 0x00000000fc2c0000, 0x0000000100000000)
//   the space 21248K,  16% used [0x00000000fae00000, 0x00000000fb171940, 0x00000000fb171a00, 0x00000000fc2c0000)

6. 空间分配担保

/**
 * -XX:+UseSerialGC -XX:+PrintGCDetails -verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:SurvivorRatio=8
 */
public class Test {
    private static final int _1MB = 1024 * 1024;

    public static void main(String[] args) {

        byte[] allocation1, allocation2, allocation3, allocation4, allocation5, allocation6, allocation7;

        allocation1 = new byte[2 * _1MB];
        allocation2 = new byte[2 * _1MB];
        allocation3 = new byte[2 * _1MB];
        // Minor GC allocation1、allocation2 和 allocation3 进入老年代
        allocation4 = new byte[2 * _1MB];// 第一次 Minor GC
        allocation5 = new byte[2 * _1MB];
        allocation6 = new byte[2 * _1MB];
        allocation1 = null;
        allocation2 = null;
        allocation3 = null;
        allocation7 = new byte[2 * _1MB];// 第二次 Minor GC
    }
}
//[GC [DefNew: 7255K->202K(9216K), 0.0047298 secs] 7255K->6346K(19456K), 0.0047709 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 
//[GC [DefNew: 6849K->6849K(9216K), 0.0000174 secs][Tenured: 6144K->6346K(10240K), 0.0046928 secs] 12993K->6346K(19456K), [Perm : 3568K->3568K(21248K)], 0.0047640 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
//Heap
// def new generation   total 9216K, used 2185K [0x00000000f9a00000, 0x00000000fa400000, 0x00000000fa400000)
//  eden space 8192K,  26% used [0x00000000f9a00000, 0x00000000f9c224e8, 0x00000000fa200000)
//  from space 1024K,   0% used [0x00000000fa300000, 0x00000000fa300000, 0x00000000fa400000)
//  to   space 1024K,   0% used [0x00000000fa200000, 0x00000000fa200000, 0x00000000fa300000)
// tenured generation   total 10240K, used 6346K [0x00000000fa400000, 0x00000000fae00000, 0x00000000fae00000)
//   the space 10240K,  61% used [0x00000000fa400000, 0x00000000faa32b98, 0x00000000faa32c00, 0x00000000fae00000)
// compacting perm gen  total 21248K, used 3598K [0x00000000fae00000, 0x00000000fc2c0000, 0x0000000100000000)
//   the space 21248K,  16% used [0x00000000fae00000, 0x00000000fb183b78, 0x00000000fb183c00, 0x00000000fc2c0000)

参考资料

https://blog.csdn.net/weixin_39788856/article/details/80388002
https://www.cnblogs.com/wcd144140/p/5649553.html
https://blog.csdn.net/v123411739/article/details/78941793

上一篇下一篇

猜你喜欢

热点阅读