概述
对象优先在Eden分配
一般情况下,对象在新生代Eden区中分配,当Eden区没有足够的空间进行分配时,虚拟机将发生一次Minor GC.
HotSpot虚拟机提供了 -XX:+PrintGCDetails这个收集器日志参数,告诉虚拟机在发生垃圾收集行为时打印内存回收日志,并且在进程退出的时候输出当前区域内存各区域各分配情况。
大对象直接进入到老年代
大对象是需要大量连续内存空间的java对象,比如很长的字符串或者数量庞大的数组,在分配空间时,它容易导致内存明明还有不少空间就提前触发了垃圾收集,以获取足够的连续空间,当复制对象时,大对象需要高额的内存复制开销,我们写程序的时候应当避免。
HotSpot虚拟机提供了-XX:PretenureSizeThreshold参数,指定该设置值得对象直接在老年代分配,这样做避免了Eden区以及两个Survivor区之间来回复制,产生大量的内存复制操作。
长期存活的对象将进入老年代
虚拟机给每个对象定义了一个年龄计数器,存储在对象头中,对象通常在Eden区诞生,如果经过了第一次Minor GC后仍旧可以存活,并且能被Survivor区容纳,该对象就会移动到Survivor空间中,将其对象设置为一岁,对象在Survivor区中每熬过Minor GC,年龄就增加一岁,当它的年龄到达一定程度(默认是15岁),就会晋升到老年代中,对象晋升到老年代的阈值,可以通过参数-XX:MaxTenuringThreshold设置。
动态对象年龄判定
虚拟机并不是永远地要求对象的年龄必须达到了-XX:MaxTenuringThreshold才能晋升老年代,如果在Survivor空间中相同年龄所有对象大小的总和大于Survivor空间的一半,年龄大于或等于该年龄的对象就可以直接进入老年代,无须等到MaxTenuringThreshold中要求的年龄。
空间分配担保
在发生Minor GC之前,虚拟机会检查老年代最大可用的连续空间是否大于新生代所有对象的总空间,
- 如果大于,则此次Minor GC是安全的
- 如果小于,则虚拟机会查看HandlePromotionFailure设置值是否允许担保失败。如果HandlePromotionFailure=true,那么会继续检查老年代最大可用连续空间是否大于历次晋升到老年代的对象的平均大小,如果大于,则尝试进行一次Minor GC,但这次Minor GC依然是有风险的;如果小于或者HandlePromotionFailure=false,则改为进行一次Full GC。
最后
以上就是甜美果汁为你收集整理的对象分配内存的全部内容,希望文章能够帮你解决对象分配内存所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复