目录
前言
引用计数法
概念
优点
缺点
可达性分析
概念
缺点:
扩展:
1.GC Roots 概念
2.STW (Stop the world)
前言
JVM有两种算法来判断对象是否存活,分别是引用计数法和可达性分析算法,针对可达性分析算法STW时间长、内存消耗等问题下可依赖三色标记法解决。
引用计数法
概念
对象中添加一个计数器,每当有一个地方引用它,计数器就加 1;
如果引用失效,计数器就减 1;
任何时候计数器为 0 的对象就是不可能再被使用的。
优点
这个方法实现简单,效率高。
缺点
很难解决对象之间相互循环引用,循环引引用会导致对象无法被回收,最终会导致内存泄漏及内存溢出。
可达性分析
概念
通过一系列的称为GC根“的对象作为起点,从这些节点开始向下搜索,节点所走过的路径称为引用链,当一个对象到GC根没有任何引用链相连的话,则证明此对象是不可用的。
过程
要两次标记:
1.第一次标记通过可达性分析算法。如果没有GC Roots相连接的引用链,那么将第一次标记
2.如果对象的 finalize()方法被覆盖并且没有执行过,则放在F-Queue队列中等待执行(不一定会执行,如果一段时间后该队列的 finalize() 方法被执行且和GC Roots关联,则移出“即将回收集合。如果仍然没有关联,则进行第二次标记,才会对该对象进行回收
代码如下:
public class TestGCRoot {
public static void main(String[] args) throws IOException {
List<Object> list = new ArrayList<>();
list.add("a");
list.add("b");
System.out.println(1);
System.in.read();
list = null;
System.out.println(2);
System.in.read();
System.out.println("end...");
}
}
缺点:
1.STW时间长
2. 内存消耗严重
扩展:
1.GC Roots 概念
GC roots是作为可达性分析算法的起点的。要实现语正确的可达性分析,就必须要能完整枚举出所有的GCRoots,否则就可能会漏扫描应该存活的对象,导致GC错误回收了这些被漏扫的活对象。那么,所谓“GC就是一组必须活跃的引用。
可以当GC roots 引用链得:
Class - 由系统类加载器(system class loader)加载的对象,这些类是不能够被回收的,他们可以以静态字段的方式保存持有其它对象。
Thread - 活着的线程
Stack Local - Java方法的local变量或参数
JNI Local - JNI方法的local变量或参数
JNI Global - 全局JNII用
Monitor Used - 被同步锁 (synchronized) 持有的对象
2.SWT (Stop the world)
Java中Stop-The-World机制简称STW,是在执行垃圾收集算法时,Java应用程序的其他所有线程都被挂起,这是Java中一种全局暂停现象,全局停顿,所有Java代码停止,native代码可以执行,但不能与JVM交互
STW产生的问题:
用户线程的运行必然会导致对象的引用关系发生改变,这就会导致两种情况:
多标: 其实就是这个对象原本应该被回收掉的垃圾对象,但是被错误的标记成了存活对象从而导致这个对象没有被GC回收掉。产生了一些浮动垃圾,下次GC再清理就可以
漏标:一个对象本来应该是存活对象,但是没有被正确的标记上,导致被错误的垃圾回收掉了