Java虚拟机学习——内存分配策略

如何判断对象已死

方法 描述
引用计数法 在Java虚拟机中不经常出现 弊端:互相引用问题,导致计数都不为0,无法通知GC收集器去回收
可达性分析算法 没有到任何引用链相连,则被判定是可回收的对象,是目前流行虚拟机常用的算法

对象优先在Eden分配

大多数情况下,对象在新生代Eden区中分配。 当Eden区没有足够空间进行分配时,虚拟机将发起一次Minor GC。

Minor GC和Full GC

新生代GC(Minor GC):指发生在新生代的垃圾收集动作,因为Java对象大多都具备朝生夕灭的特性,所以Minor GC非常频繁,一般回收速度也比较快。
老年代GC(Major GC/Full GC):指发生在老年代的GC,出现了Major GC,经常会伴随至少一次的Minor GC(但非绝对的,在Parallel Scavenge收集器的收集策略里就有直接进行Major GC的策略选择过程)。 Major GC的速度一般会比Minor GC慢10倍以上。

大对象直接进入老年代

所谓的大对象是指,需要大量连续内存空间的Java对象,最典型的大对象就是那种很长的字符串以及数组
(朝生夕灭的大对象对虚拟机是最坏的消息)
新生代采用复制算法收集内存,所以要避免大对象频繁复制

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

如果对象在Eden出生并经过第一次Minor GC后仍然存活,并且能被Survivor容纳的话,将被移动到Survivor空间中,并且对象年龄设为1。 对象在Survivor区中每“熬过”一次Minor GC,年龄就增加1岁,当它的年龄增加到一定程度(默认为15岁),就将会被晋升到老年代中。

在发生Minor GC之前,虚拟机会先检查老年代最大可用的连续空间是否大于新生代所有对象总空间,如果这个条件成立,那么Minor GC可以确保是安全的。 如果不成立,则虚拟机会查看HandlePromotionFailure设置值是否允许担保失败。 如果允许,那么会继续检查老年代最大可用的连续空间是否大于历次晋升到老年代对象的平均大小,如果大于,将尝试着进行一次Minor GC,尽管这次Minor GC是有风险的;如果小于,或者HandlePromotionFailure设置不允许冒险,那这时也要改为进行一次Full GC。

总结

一般来说,对象实例化之后首先会进入Eden区,Eden区进行Minor GC之后,依然存活的对象会进入Survivor区,Survivor区有两个,是因为虚拟机使用了复制算法。当对象在Survivor区存活到一定年龄后,对象就会进入老年代。

HotSpot虚拟机默认的Eden区和Survivor区大小比例为8:1

发布了154 篇原创文章 · 获赞 142 · 访问量 35万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览