4.GC算法和种类
这里主要介绍:
-GC概念
-GC算法
-引用计数
-标记清除
-标记压缩
-复制算法
-可触及性
-Stop the world
1.GC概念
后台有个线程一直跑着,监控堆空间和永久区,释放空间。C++
2.GC算法
引用计数法:


标记清除:标记-清除算法是现代垃圾回收算法的思想基础。标记-清除算法将垃圾回收分为两个阶段:标记阶段和清除阶段。一种可行的实现是,在标记阶段,首先通过根节点,标记所有从根节点开始的可达对象。因此,未被标记的对象就是未被引用的垃圾对象。然后,在清除阶段,清除所有未被标记的对象。

标记压缩:标记-压缩算法适合用于存活对象较多的场合,如老年代。它在标记-清除算法的基础上做了一些优化。和标记-清除算法一样,标记-压缩算法也首先需要从根节点开始,对所有可达对象做一次标记。但之后,它并不简单的清理未标记的对象,而是将所有的存活对象压缩到内存的一端。之后,清理边界外所有的空间。

复制算法:与标记-清除算法相比,复制算法是一种相对高效的回收方法 不适用于存活对象较多的场合 如老年代 将原有的内存空间分为两块,每次只使用其中一块,在垃圾回收时,将正在使用的内存中的存活对象复制到未使用的内存块中,之后,清除正在使用的内存块中的所有对象,交换两个内存的角色,完成垃圾回收

由上至下,三块区域:伊甸园,幸存代,老年代。复制算法发生在幸存代。伊甸园的数据,大对象直接进入老年代,一部分进入s1区,s0的将保留的复制到s1,将垃圾的清除,将被标记为老年的放入老年代。
总结:
依据对象的存活周期进行分类,短命对象归为新生代,长命对象归为老年代。 根据不同代的特点,选取合适的收集算法 少量对象存活,适合复制算法 大量对象存活,适合标记清理或者标记压缩

3.可触及性:
可触及的 从根节点可以触及到这个对象
可复活的 一旦所有引用被释放,就是可复活状态 因为在finalize()中可能复活该对象
不可触及的 在finalize()后,可能会进入不可触及状态不可触及的对象不可能复活 可以回收
经验:避免使用finalize(),操作不慎可能导致错误。 优先级低GC发生时调用,何时被调用, 不确定 何时发生GC不确定 可以使用try-catch-finally来替代它
package com.calihua; public class CanReliveObj { public static CanReliveObj obj; //所有对象的该方法只调用一次 @Override protected void finalize() throws Throwable { super.finalize(); System.out.println("CanReliveObj finalize called"); obj = this; } @Override public String toString() { return "I am CanReliveObj"; } public static void main(String[] args) throws InterruptedException { obj = new CanReliveObj(); obj = null; // 可复活
//将对象救活了 System.gc(); Thread.sleep(1000); if (obj == null) { System.out.println("obj 是 null"); } else { System.out.println("obj 可用"); } System.out.println("第二次gc"); obj = null; // 不可复活 System.gc(); Thread.sleep(1000); if (obj == null) { System.out.println("obj 是 null"); } else { System.out.println("obj 可用"); } } }
4.Stop-The-World
GC 垃圾回收线程暂停,新生代若干秒,老年代几十分钟,时间不确定,暂时对这块不是很明白。
浙公网安备 33010602011771号