这是我参与8月更文挑战的第3天
如果从对象消亡的角度出发,垃圾收集算法可以划分成“引用计数式垃圾收集“(直接垃圾收集)和”追踪式垃圾收集“(间接垃圾收集)两大类。由于引用式垃圾收集算法在主流Java虚拟机中均为涉及,以下内容皆以追踪式垃圾收集为基础。
分代收集理论
弱分代假说
绝大多数对象都是朝生熄灭的
强分代假说
熬过越多次垃圾收集过程的对象就越难以消亡
这两个分代假说共同奠定了常用的垃圾收集器的一致设计原则:收集器应该将Java堆划分出不同的区域,然后将回收对象依据其年龄(对象熬过垃圾收集过程的次数)分配到不同的区域之中存储。
在Java堆划分出不同的区域后,垃圾收集器才可以每次只回收其中某一个或者某部分的区域。 设计者一至少会把Java堆划分为新生代、老年代两个区域。
但是只是简单的划分两个区域是远远不够的,假设有这样一个场景,现在进行一次局限于新生代区域内的收集。但是新生代的对象是完全可以被老年代的对象所引用的,如果这时进行可达性分析遍历整个老年代,那这样无疑对内存回收带来巨大压力。
所以,第三条分代理论诞生了
跨代引用假说
跨代引用相对于同代引用来说仅占极少数
存在相互引用关系的两个对象,是应该倾向于同时生存或者同时消亡的。举个例子:假如老年代引用新生代的某个对象,那么这个对象将在每次垃圾回收时存活,从而一起晋升老年代。
根据这条假说,每次就不在为了少量的跨代引用,而去扫描整个老年代。只需要在新生代上建立一个全局数据结构(“记忆集”),会把老年代划分出若干个小块,记录老年代哪一块内存会存在跨代引用。所以在新生代进行垃圾收集时,只需要扫描这一块内存空间即可。