对象存活的判断

引用计数法(Reference Counting)

在对象中添加一个引用计数器,每当有一个地方引用它时,计数器值加一;

引用失效时,计数器值减一;计数器值为零的对象表示不再使用。

此方式有循环引用的问题,即A引用BB引用A,不做处理,最终AB均无法回收。

主流的Java虚拟机没有使用此方式。

Netty中的引用计数法
ByteBuf byteBuf = ctx.alloc().directBuffer(); // netty中分配直接内存
System.out.println(byteBuf.refCnt()); // 初始化引用计数值为1
byteBuf.retain(); // CAS 引用计数加1
byteBuf.release(); // CAS 引用计数减1

可达性分析算法(Reachability Analysis)

通过一些列GC Roots的根对象作为起点,搜索其引用的对象,

搜索时经过的路径称为引用链(Reference Chain),

如果对象不在任何引用链中,则表示不再使用。

可作为GC Roots的对象
  • 在虚拟机栈(栈桢中的本地变量表)中引用的对象

    正在执行的方法所引用的对象自然是存活的

  • 在方法区中类静态属性引用的对象

    除非类型卸载,否则静态属性引用的对象也应该是存活的

  • 在方法区中常量引用的对象(字符串常量池里的引用)

  • 在本地方法栈中JNI(就是Native方法)引用的对象
  • Java虚拟机内部的引用,如基本数据类型对应的Class对象、常驻的异常对象、类加载器等
  • 所有被同步锁持有的对象
  • 反映Java虚拟机内部情况的JMXBeanJVMTI中注册的回调、本地代码缓存等。