垃圾回收算法核心思想:
1.找到内存中存活的对象(可达性分析法)
2.释放不再存活对象的内存,使得程序能再次利用这部分空间
四种垃圾回收算法:
标记-清楚算法、复制算法、标记-整理算法、分代GC
垃圾回收算法的评价标准:
1.吞吐量
即CPU用于执行用户代码的时间与CPU总执行之间的比值。吞吐量越高,垃圾回收效率越高。
2.最大暂停时间
即垃圾回收过程中的STW时间最大值。最大暂停时间越短,用户使用系统时受到的影响就越短。
3.堆使用效率
不同垃圾回收算法对堆的使用方式是不同的。如标记清楚算法可以使用完整的堆内存,而复制伏算法会将堆内存一分为二,每次只能使用一半内存。从堆效率上来说,标记清楚算法要优于复制算法。
上述三种评价标准不可兼得。一般堆内存越大,回收的对象越多,最大暂停时间越长。想要减少最大暂停时间,可能会分成多次回收,一些准备工作重复执行,就会降低吞吐量。不同的垃圾回收算法适用于不同的场景。
标记-清楚算法
标记阶段:将所有存活的对象进行标记,使用可达性分析算法,从 GC Root开始 通过引用链遍历出所有存活对象。
清楚阶段:从内存中删除没有被标记,即非存活对象。
优点:实现简单,只需要第一个阶段给每个对象维护标志位,第二阶段删除对象即可。
缺点:
1.碎片化问题
2.分配速度慢。
复制算法
1.准备两块空间From空间和To空间,每次在对象分配阶段,只能使用其中一块空间(From空间)。
2.在垃圾回收阶段,如果一个对象在回收过程中还存活,那么他就会被搬运到To空间。
3.将From和To空间的名字互换。(因为现在To空间存有对象,而对象存放的空间永远叫做From空间)
标记-整理算法
对标记清理算法中容易产生内存碎片问题的一种解决方案。
1.标记阶段。将所有存活的对象进行标记,使用可达性分析算法。
2.整理阶段。将存活对象移动到堆的一端,清理掉未存活对象的内存空间。
分代GC算法(应用最广泛)
分代垃圾回收将整个内存区域分为年轻代和老年代,年轻代存放存活时间比较短的对象,老年代存放存活时间比较长的对象。
在年轻代中,若幸存者区满了,即使有些对象年龄还没到,也会被放入老年区。老年区也同理。即上图中老年代空间不足先尝试minor gc。