• 读《深入理解jvm虚拟机》之长期存活对象进入老年代,有感!!!!


    关于这一段代码 有几个不是让人很理解的地方,我一一说来。

    1.Desired survivor size 524288 bytes

      关于这个512KB空间是怎么来的,JVM有这样一个参数:

      -XX:TargetSurvivorRatio:目标存活率,默认为50%,表明所有age的survivor space对象的大小如果超过Desired survivor size,则重新计算threshold,以age和MaxTenuringThreshold的最小值为准,否则以MaxTenuringThreshold为准.

      简单的说,如果要分配的Survivor空间是1M那么,desired survivor size 就是512KB,这个大小影响的是Tenuring Threshold参数

      当你试图放入800KB的对象是,Survivor from是运行你放入的,但是Tenuring Threshold大小会变成1(就算你之前是15,这里也会动态改成1),即下次GC发生时,age=1的统统放入老年代

    2.Eden,Survivor from,to的关系

      对象分配空间的时候,若Eden仍有区域时,都会将对象放置Eden,持续新增对象一段时间后,Eden无法容纳时,这个时候就会发生一次Minor GC。

      当发生Minor GC时,会将Eden和 Survivor from中的幸存对象存放在Survivor to中,同时这些对象的age+1。

      若Survivor to无法容纳幸存对象,就将无法容纳的对象放置在永久带中。

      当GC时,存在对象的age=Tenuring Threshold时,不管Survivor to是否空间足够,都将他们放入永久代。

    发生GC的前提,放入对象时空间不够,放入对象后空间占用完毕。


    这段例子中,当XX:MaxTenuringThreshold=1时

    a1 = 0.25M,a2=4M;

    分配a3=4M时,Eden无法容纳4M的对象了,发起Minor GC,此时a1,a2 age=1,

    这个时候,Survivor最大容量1M,无法同时容纳存活的4.5M a1,a2

    虚拟机将4M的a2放入老年代,同时将0.25M的a1放入Survivor to中,此时空间分布Eden(0M),Survivor from(0.25M),Old(4M)

    放入4M的a3,此时空间分布Eden(4M),Survivor from(0.25M),Old(4M)

    a3=null;只是说明了a3无引用,但是数组空间仍然存在,只是提示jvm我下次可以被回收了

    a3=4M,又分配了4M的空间,这个时候Eden 4+4=8M 已经满了,触发一次GC(这时,jvm会清理age=1的对象,a1,a2被放在了老年代)

    发现之前创建的4M数组没有GC Root相关联,而且不符合自救规则,回收。

    此时空间分布Eden(4M),Survivor from(0M),Old(4.25M)

    /**
         * VM参数:-verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8 -XX:MaxTenuringThreshold=1 -XX:+PrintTenuringDistribution
         * 
         */
        @SuppressWarnings("unused")
        public static void testTenuringThreshold() {
            byte[] allocation1, allocation2, allocation3;
            allocation1 = new byte[_1MB / 4];  //262144 什么时候进入老年代决定于XX:MaxTenuringThreshold设置
            allocation2 = new byte[4 * _1MB]; //4194304
            allocation3 = new byte[4 * _1MB];
            allocation3 = null;
            allocation3 = new byte[4 * _1MB];
        /**
             * 
             * XX:MaxTenuringThreshold=1
             [GC [DefNew
                    Desired survivor size 524288 bytes, new threshold 1 (max 1)
                    - age   1:     418144 bytes,     418144 total
                    : 4695K->408K(9216K), 0.0054252 secs] 4695K->4504K(19456K), 0.0054708 secs] [Times: user=0.02 sys=0.00, real=0.01 secs] 
                    [GC [DefNew
                    Desired survivor size 524288 bytes, new threshold 1 (max 1)
                    - age   1:        136 bytes,        136 total
                    : 4668K->0K(9216K), 0.0013601 secs] 8764K->4504K(19456K), 0.0013867 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
                    Heap
                     def new generation   total 9216K, used 4260K [0x32750000, 0x33150000, 0x33150000)
                      eden space 8192K,  52% used [0x32750000, 0x32b78fe0, 0x32f50000)
                      from space 1024K,   0% used [0x32f50000, 0x32f50088, 0x33050000)
                      to   space 1024K,   0% used [0x33050000, 0x33050000, 0x33150000)
                     tenured generation   total 10240K, used 4504K [0x33150000, 0x33b50000, 0x33b50000)
                       the space 10240K,  43% used [0x33150000, 0x335b60a0, 0x335b6200, 0x33b50000)
                     compacting perm gen  total 12288K, used 377K [0x33b50000, 0x34750000, 0x37b50000)
                       the space 12288K,   3% used [0x33b50000, 0x33bae5c0, 0x33bae600, 0x34750000)
                        ro space 10240K,  55% used [0x37b50000, 0x380d1140, 0x380d1200, 0x38550000)
                        rw space 12288K,  55% used [0x38550000, 0x38bf44c8, 0x38bf4600, 0x39150000)
             */
    }

       

    这段例子中,当XX:MaxTenuringThreshold=8时

    a1 = 0.25M,a2=4M;

    分配a3=4M时,Eden无法容纳4M的对象了,发起Minor GC

    这个时候,Survivor最大容量1M,无法同时容纳存活的4.5M a1,a2

    虚拟将4M的a2放入老年代,同时将0.25M的a1放入Survivor to中,此时空间分布Eden(0M),Survivor from(0.25M),Old(4M)

    放入3M的a3,此时空间分布Eden(4M),Survivor from(0.25M),Old(4M)

    a3=null;只是说明了a3无引用,但是数组空间仍然存在,只是提示jvm我下次可以被回收了

    a3=4M,又分配了4M的空间,这个时候Eden 4+4=8M 已经满了,触发一次GC

    发现之前创建的4M数组没有GC Root相关联,而且不符合自救规则,回收。

    此时空间分布Eden(4M),Survivor from(0.25M),Old(4M)

    /**
             * 
             * XX:MaxTenuringThreshold =8
             [GC [DefNew
                    Desired survivor size 524288 bytes, new threshold 8 (max 8)
                    - age   1:     418144 bytes,     418144 total
                    : 4695K->408K(9216K), 0.0036693 secs] 4695K->4504K(19456K), 0.0036983 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
                    [GC [DefNew
                    Desired survivor size 524288 bytes, new threshold 8 (max 8)
                    - age   1:        136 bytes,        136 total
                    - age   2:     417936 bytes,     418072 total
                    : 4668K->408K(9216K), 0.0010034 secs] 8764K->4504K(19456K), 0.0010296 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
                    Heap
                     def new generation   total 9216K, used 4668K [0x32750000, 0x33150000, 0x33150000)
                      eden space 8192K,  52% used [0x32750000, 0x32b78fe0, 0x32f50000)
                      from space 1024K,  39% used [0x32f50000, 0x32fb6118, 0x33050000)
                      to   space 1024K,   0% used [0x33050000, 0x33050000, 0x33150000)
                     tenured generation   total 10240K, used 4096K [0x33150000, 0x33b50000, 0x33b50000)
                       the space 10240K,  40% used [0x33150000, 0x33550010, 0x33550200, 0x33b50000)
                     compacting perm gen  total 12288K, used 377K [0x33b50000, 0x34750000, 0x37b50000)
                       the space 12288K,   3% used [0x33b50000, 0x33bae5b8, 0x33bae600, 0x34750000)
                        ro space 10240K,  55% used [0x37b50000, 0x380d1140, 0x380d1200, 0x38550000)
                        rw space 12288K,  55% used [0x38550000, 0x38bf44c8, 0x38bf4600, 0x39150000)
             */
  • 相关阅读:
    DDD(Domain Driven Design) 架构设计
    兴哥:美团下一个十年,要让新一批管理者成长起来
    Java设计模式-Builder构造者模式
    社会需要转型变革,自己更需要转型变革-屡败屡战
    Guava 源码分析之Cache的实现原理
    缓存算法(FIFO 、LRU、LFU三种算法的区别)
    Guava---缓存之LRU算法
    Boost.Asio 网络编程([译]Boost.Asio基本原理)
    浅谈 Boost.Asio 的多线程模型
    boost.asio系列——io_service
  • 原文地址:https://www.cnblogs.com/Yiran583/p/8795415.html
Copyright © 2020-2023  润新知