目前来说Java堆中的对象是分为新生代和老年代,对于新生代中的对象采用的是复制算法清理
1、复制算法
它将可用内存空间划分为一块较大的Eden空间和两块较小的From Survivor(S0)和To Survivor(S1)空间。每次使用时只使用Eden和其中一块S区。比如这次使用的是S0区。回收时将Eden和S0区中的中还存活的对象一次性复制到S1中最后再清理Eden和S0中的对象,HotSpot虚拟机默认Eden:S0:S1之间大小比例是8:1:1,这是因为新生代中对象大多数甚至98%的都是“朝生夕死”。如果S区的大小不够那么就会依赖老年代的内存进行分配担保。
2、对象从新生代变成老年代的判定方法
每经历一次Minor GC(复制算法回收对象)就会让对象的年龄加一,当对象年龄为15时就会把新生代的对象放入老年代中。
如果Survivor区中的存放不下的对象就会放入老年代中:对象会优先在Eden区中分配,而后通过一次Minor GC就让对象进入Survivor区中,当Survivor区中存放不下该对象时就会将该对象放入老年代。
新生成的大对象也会直接放入老年代中(可以通过-XX:+PretenuerSizeThreshold设置)超过这个size的对象一生成就会放入老年代。
3、标记—清理与标记—整理算法
在老年代中因为对象存活率高,没有额外的空间对它进行分配担保,所以会采用标记—清理或标记—整理算法来进行回收对象
标记—清理算法:首先标记出所有需要回收的对象,在标记完成之后统一回收所有标记的对象
标记—整理算法:先标记所有可回收对象,让存活的对象向一端移动,然后直接清理掉端边界以外的内存
上面的标记过程都是根据可达性分析算法中对象标记判定来实现的。
如果大家对java架构相关感兴趣,可以关注下面公众号,会持续更新java基础面试题, netty, spring boot,spring cloud等系列文章,一系列干货随时送达, 超神之路从此展开, BTAJ不再是梦想!