JavaSE---内存分配

1、普遍的内存分配规则

    1.1、对象优先在Eden分配

        a,大多数情况下,对象在新生代Eden分配;

        b,当Eden没有足够空间进行分配时,虚拟机发起一次Minor GC;

        c,虚拟机  提供了  -XX:+PrintGCDetails (GC日志参数),告诉虚拟机 在发生GC行为时打印内存回收日志,并  在进程退出时输出 当前内存各区域的分配情况

    1.2、大对象直接进入老年代

        a,大对象:需要   大量连续内存空间   的java对象(eg:长字符串、数组...);

        b,大对象  对  JVM的内存分配来说是一个坏消息;

            避免 创建很多  朝生夕灭  的短命大对象

        c,经常出现大对象  容易导致  内存还有不少空间 就提前 触发GC 以获取更足够的连续空间 存储;

        d,虚拟机 提供了 -XX:PretenureSizeThreshold大于这个值的对象直接进入老年代);

            避免 在Eden和Survivor之间发生大量内存拷贝

            PretenureSizeThreshold只对Serial、ParNew 收集器 有效;  

    1.3、长期存活的对象将进入老年代

        a,虚拟机 给每个对象 定义了一个  对象年龄计数器

            如果对象在Eden经过第一次Minor GC后仍然存活 且 被Survivor容纳,将被移动到Survivor空间,并设置年龄为1;

            对象在Survivor每经历一次Minor GC,年龄增加1;

            当对象的年龄增加到 一定程度(默认15岁),被晋升到 老年代

        b,虚拟机 提供了 -XX:MaxTenuringThreshold (对象晋升老年代的年龄阈值);

    1.4、动态对象年龄判定

        a,为了更好地适应不同程序的内存状况,虚拟机 不总是要求对象年龄 必须达到MaxTenuringThreshold才晋升 老年代;

        b,如果 在Survivor中  相同年龄的所有对象大小的总和  大于 Survivor的一半,年龄大于或等于该年龄的对象直接进入老年代;

    1.5、空间分配担保

        a,发生Minor GC时,虚拟机会 检测 之前每次晋升到老年代的平均大小 是否大于 老年代剩余空间

            大于,改为进行Full GC;

            小于,查看HandlerPromotionFailure设置是否允许担保失败:

                  允许,只会进行Minor GC;

                  不允许,进行Full GC;

 

        

posted on 2020-04-14 17:26  anpeiyong  阅读(128)  评论(0编辑  收藏  举报

导航