• 实验: survivor放不下的对象进入老年代


    实验一: 存活对象包含 小于survivor大小的对象 + 大于survivor的对象

     private static final Integer _1MB = 1024 * 1024;
    
        /**
         * -XX:+UseSerialGC -Xms20M -Xmx20M  -Xmn10M -XX:+PrintGCDetails
         * eden=8m survivor=1m old=10m
         * @param args
         */
        public static void main(String[] args) {
    
            byte[] a1 = new byte[_1MB * 2];
            byte[] a2 = new byte[_1MB * 2];
            byte[] a3 = new byte[_1MB/2];
    
            //第一次minor gc:创建a4的时候,eden 放不下,要先进行一次minor gc
            //survivor=1M,放得下a3, 放不下a1和a2
            byte[] a4 = new byte[_1MB * 4];
        }
    

    gc日志分析

    [GC (Allocation Failure) [DefNew: 6837K->1023K(9216K), 0.0073394 secs] 6837K->5146K(19456K), 0.0073686 secs] [Times: user=0.01 sys=0.00, real=0.00 secs]
    年轻代回收了4m左右,但是总的堆占用还有5m, 减去年轻代的1023k 得出老年代占用4m左右 和下面打印的回收后日志匹配

    Heap
    def new generation total 9216K, used 5256K [0x00000007bec00000, 0x00000007bf600000, 0x00000007bf600000)
    eden space 8192K, 51% used [0x00000007bec00000, 0x00000007bf0223b8, 0x00000007bf400000)
    from space 1024K, 99% used [0x00000007bf500000, 0x00000007bf5ffff8, 0x00000007bf600000)
    to space 1024K, 0% used [0x00000007bf400000, 0x00000007bf400000, 0x00000007bf500000)
    tenured generation total 10240K, used 4122K [0x00000007bf600000, 0x00000007c0000000, 0x00000007c0000000)
    the space 10240K, 40% used [0x00000007bf600000, 0x00000007bfa06b88, 0x00000007bfa06c00, 0x00000007c0000000)
    Metaspace used 2956K, capacity 4496K, committed 4864K, reserved 1056768K
    class space used 329K, capacity 388K, committed 512K, reserved 1048576K

    回收后,老年代占用 4122k约等于4m 刚好是a1 + a2的大小 说明a3并没有进入老年代,还在survivor区
    ps: 这边有500k左右的未知对象 忽略

    实验二: 存活对象总大小 > survivor, 单个对象都小于survivor

    private static final Integer _1MB = 1024 * 1024;
    
        /**
         * -XX:+UseSerialGC -Xms20M -Xmx20M -Xmn10M  -XX:+PrintGCDetails
         * eden=8m survivor=1m old=10m
         * @param args
         */
        public static void main(String[] args) {
            byte[] a1 = new byte[_1MB/2];
            byte[] a2 = new byte[_1MB/2];
            byte[] a3 = new byte[_1MB/2];
    
            //a1+a2+a3=1.5M, 要创建a4=7M 放不下,需要先进行minor gc
            // a1+a2+a3 > survivor 这种情况,谁会进入老年代?
            byte[] a4 = new byte[_1MB * 7];
        }
    

    gc日志分析

    [GC (Allocation Failure) [DefNew:3765K->1023K(9216K), 0.0018177 secs] 3765K->2074K(19456K), 0.0018397 secs] [Times: user=0.01 sys=0.00, real=0.00 secs]
    Heap
    def new generation total 9216K, used 8410K [0x00000007bec00000, 0x00000007bf600000, 0x00000007bf600000)
    eden space 8192K, 90% used [0x00000007bec00000, 0x00000007bf336bc0, 0x00000007bf400000)
    from space 1024K, 99% used [0x00000007bf500000, 0x00000007bf5ffff8, 0x00000007bf600000)
    to space 1024K, 0% used [0x00000007bf400000, 0x00000007bf400000, 0x00000007bf500000)
    tenured generation total 10240K, used 1050K [0x00000007bf600000, 0x00000007c0000000, 0x00000007c0000000)
    the space 10240K, 10% used [0x00000007bf600000, 0x00000007bf706928, 0x00000007bf706a00, 0x00000007c0000000)
    Metaspace used 2956K, capacity 4496K, committed 4864K, reserved 1056768K
    class space used 329K, capacity 388K, committed 512K, reserved 1048576K

    a1=a2=a3=0.5m 单个都小于survivor=1m,minor gc时他们都还存活 a1 + a2 + a3=1.5M > survivor=1M 总空间大于survivor,gc后老年代仅增加 1050k约等于1m,from区塞满,说明 a1/a2/a3只有2个对象进入老年代 还一个家伙被留到survivor中

    结论

    minor gc后,如果存活对象过多 survivor区放不下,并不是所有的存活对象都直接进入老年代,而是放不下的那部分对象才进入老年代

    本文来自博客园,作者:mushishi,转载请注明原文链接:https://www.cnblogs.com/mushishi/p/14546697.html

  • 相关阅读:
    关于前端框架讨论的链接
    和BEM的战斗:10个常见问题及如何避免
    BEM —— 源自Yandex的CSS 命名方法论
    JavaScript 语句后应该加分号么?
    彻底搞懂word-break、word-wrap、white-space
    ios UIImageWriteToSavedPhotosAlbum报错 NSPhotoLibraryAddUsageDescription
    Emmet使用手册
    vue-cli入门之项目结构分析
    ios移动端原生滚动条滚动不灵敏问题
    ios点击事件失效
  • 原文地址:https://www.cnblogs.com/mushishi/p/14546697.html
Copyright © 2020-2023  润新知