您的位置:首页 > 其它

JVM之二——对象内存的分配和回收

2014-07-04 21:58 260 查看

大部分对象在初始时被分配在Eden中

大部分的对象在初始的时候都是被分配在Eden(伊甸园,很形象)中。

较大的对象直接分配到Old Generation中

一些较大的对象可能会被直接分配到Old Generation中,虚拟机提供了一个XX:PretenureSizeThreshold参数,令大于这个值的对象直接在老年代中分配。

分代回收

若系统为对象在Eden上分配空间时,Eden上空间不足,则会触发一次Young Generation上的GC,也叫作minor collection。

由于大部分的对象都是朝生暮死的,也就是说很多都活不到一次GC,所以minor collection的时候只有少量的存活对象。那么,复制算法对于minor
collection来说则是一种相对较好的算法,只需要少量的复制成本。

复制算法:

Young Generation上除了Eden区外,还有两块Survivor区(From 和 To),这两块区域就是为了复制而存在的。
当minor collection被触发时,系统会将Eden中的活动对象直接复制到初始为空的Survivor区中(也就是To区),如果有些对象占用空间特别大,垃圾回收器会直接将其复制到Old代中。对于From Survivor区中的活动对象(该对象至少经历过一次垃圾回收),到底是复制到To Survivor区中,还是复制到Old
Generation中,则取决于这个对象的生存时间:JVM为每个对象定义了一个对象年龄Age,每经过一次新生代GC后任然存活,将对象的年龄Age增加1岁,当年龄到一定程度(默认为15)时,将会被晋升到老年代中,对象晋升老年代的年龄限定值,可通过-XX:MaxTenuringThreshold来设置。
完成上面复制之后,Eden和From Survivor区中剩下的都是不可达的对象了,系统直接回收Eden区和From Survivor区的所有内存,而原来空的To Survivor区则保存了存活对象。在下一次回收时,原本的From Survivor区将变为To Survivor区,原本的To Survivor区将变为From Survivor区。

标记——清除——压缩算法:

垃圾回收器对Old Generation采用标记压缩算法(mark-sweep-compact),这个算法有三个阶段:mark(标记存活对象),sweep(清除未标记的对象),compact(压缩)。在mark阶段,回收器会标记出哪些对象是存活的。在sweep阶段,回收器会清除未标记对象所占用的内存。而在compact阶段,回收器会把存活对象往Old Generation的前端移动,而在后端保留出一块连续的内存空间,以便下次为新对象分配内存。

下图是JVM在堆空间中申请新对象过程的活动图(包括2种GC的触发时机):

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: