本文涉及:垃圾对象的判定、常见垃圾收集算法
哪些对象需要回收
判断对象是否需要回收的算法有引用计数法和可达性分析法
引用计数法
为每个对象标记一个引用数量,当这个对象被另外一个对象引用时它的引用数据就加一,当另外一个对象释放了对它的引用它的引用数量就减一。当它的引用变为0时意味着没有对象引用,就可以回收了
引用计数法存在的问题
系统无时无刻不在进行引用的增加和修改,引用和去引用伴随着加减法,非常影响性能
很难处理循环引用,例如下图右面三个对象互相持有对方的引用则无法处理
可达性分析
通过设置一个跟节点,如果从根节点出发没有任何路径到达一个对象,则标记这个对象为不可达对象,当一个对象被标记了2次不可达对象之后将面临回收
垃圾收集算法
标记清除法
首先标记所有需要回收的对象,在标记完成后统一回收掉所有被标记的对象
缺点
标记和清除的效率都不高
标记清除后会产生大量的不连续空间
复制算法
将原有的内存空间分为两块。每次只使用其中一块,在垃圾回收时,将正在使用的内存空间的存活的对象全都复制到未使用的那块内存空间,然后清除正在使用的那块内存,再交换两个角色,完成垃圾回收
缺点
空间浪费
标记压缩法
第一步标记阶段与标记清除法一样,标记所有需要回收的对象,接着把所有需要回收的对象全都压缩到内存的一端,之后再进行清理
分代收集
分代收集法是目前大部分 JVM 所采用的方法,其核心思想是根据对象存活的不同生命周期将内存划分为不同的域,然后根据不同域的特点选择不同的算法
新生代因为每次垃圾回收都需要回收大量的对象,故使用复制算法
老年代因为每次回收少量对象,使用标记整理对象
分区收集算法
分区算法则将整个堆空间划分为连续的不同小区间, 每个小区间独立使用, 独立回收. 这样做的好处是可以控制一次回收多少个小区间 , 根据目标停顿时间, 每次合理地回收若干个小区间(而不是整个堆), 从而减少一次 GC 所产生的停顿
万水千山总是情,点个 “在看” 行不行!!!
