如何确定对象可回收
引用计数算法
- 给对象中添加一个引用计数器,每当有一个地方引用它的时候,计数器就加1;当引用失效时,计数器值就减1;任何时刻计数器为0的对象是不可能被使用的。
- 但是JVM并没有使用引用计数来管理内存,其中最重要的原因就是它很难解决对象之间的相互引用关系。
可达性分析算法
- 通过一系列的“GC Roots”对象作为起点进行搜索,如果在“GC Roots”和一个对象之间没有可达路径,则称该对象是不可达的,不过要注意的是被判定为不可达的对象不一定就会成为可回收对象。被判定为不可达的对象要成为可回收对象必须至少经历两次标记过程,如果在这两次标记过程中仍然没有逃脱成为可回收对象的可能性,则基本上就真的成为可回收对象了。
垃圾回收算法
标记清除算法
-
最基础的垃圾回收算法,分为两个阶段,标注和清除。标记阶段标记出所有需要回收的对象,清 除阶段回收被标记的对象所占用的空间。
-
该算法最大的问题是内存碎片化严重,后续可能发生大对象不能找到可 利用空间的问题。
复制算法
-
为了解决 Mark-Sweep 算法内存碎片化的缺陷而被提出的算法。按内存容量将内存划分为等大小
的两块。每次只使用其中一块,当这一块内存满后将尚存活的对象复制到另一块上去,把已使用
的内存清掉。
-
这种算法虽然实现简单,内存效率高,不易产生碎片,但是最大的问题是可用内存被压缩到了原
本的一半。且存活对象增多的话,Copying 算法的效率会大大降低。
标记整理算法
-
结合了以上两个算法,为了避免缺陷而提出。标记阶段和 Mark-Sweep 算法相同,标记后不是清
理对象,而是将存活对象移向内存的一端。然后清除边界外的对象。
分代收集算法
- 年轻代使用复制算法
- 老年代使用标记整理算法
分区收集算法
-
分区算法则将整个堆空间划分为连续的不同小区间, 每个小区间独立使用, 独立回收. 这样做的
好处是可以控制一次回收多少个小区间 , 根据目标停顿时间, 每次合理地回收若干个小区间(而不是
整个堆), 从而减少一次 GC 所产生的停顿。