判断一个对象是否存活,分为两种算法1:引用计数法;2:可达性分析算法;
一、引用计数法:
给每一个对象设置一个引用计数器,当有一个地方引用该对象的时候,引用计数器就+1
,引用失效时, 引用计数器就-1
;当引用计数器为
0
的时候,就说明这个对象没有被引用,也就是垃圾对象,等待回收;
缺点:无法解决循环引用的问题,当A
引用
B,
B
也引用
A
的时候,此时
AB
对象的引用都不为
0
,此时也就无法垃圾回收,所以一般主流虚拟机都不采用这个方法;
二、可达性分析法
从一个被称为GC Roots
的对象向下搜索,如果一个对象到
GC Roots
没有任何引用链相连接时,说明此对象不可用,在java
中可以作为
GC Roots
的对象有以下几种:
1、虚拟机栈中引用的对象
2、方法区类静态属性引用的变量
3、方法区常量池引用的对象
4、本地方法栈JNI
引用的对象
但一个对象满足上述条件的时候,不会马上被回收,还需要进行两次标记;
第一次标记:判断当前对象是否有finalize()方法并且该方法没有被执行过,若不存在则标记为垃圾对象,等待回收;若有的话,则进行第二次标记;
第二次标记将当前对象放入F-Queue队列,并生成一个
finalize
线程去执行该方法,虚拟机不保证该方法一定会被执行,这是因为如果线程执行缓慢或进入了死锁,会导致回收系统的崩溃; 如果执行了finalize
方法之后仍然没有与
GC Roots
有直接或者间接的引用,则该对象会被回收。