垃圾回收有两种方法分别是引用计数法和可达性分析法:
判断垃圾
引用计数法
public class Main {
public static void main(String[] args) {
MyObject object1 = new MyObject();
MyObject object2 = new MyObject();
object1.object = object2;
object2.object = object1;
object1 = null;
object2 = null;
}
}
class MyObject{
public Object object = null;
}
最后面两句将object1和object2赋值为null,也就是说object1和object2指向的对象已经不可能再被访问,但是由于它们互相引用对方,导致它们的引用计数都不为0,那么垃圾收集器就永远不会回收它们。
给对象中添加一个引用计数器,每当有一个地方引用它,计数器就加1;当引用失效,计数器就减1;任何时候计数器为0的对象就
是不可能再被使用的。引用计数器存在循环引用的问题
可达性分析法
对象Object5 —Object7之间虽然彼此还有联系,但是它们到 GC Roots 是不可达的,因此它们会被判定为可回收对象。
通过一系列的称为GC Roots的对象作为起点,从这些节点开始向下搜索,节点所走过的路径称为引用链,当一个对象到 GC
Roots 没有任何引用链相连的话,则证明此对象是不可用的。
1.虚拟机栈中的本地变量表
2.方法区中静态变量引用的对象
3.方法区中常量引用的对象
4.JNI(native)方法引用的对象
5.类加载器引用的对象
四大引用
1.强引用(StrongReference):垃圾回收器绝不会回收它。当内存空间不足,Java虚拟机宁愿抛出内存溢出错误。
2.软引用(SoftReference):如果内存空间不足了,就会回收这些对象的内存。
3.弱引用(WeakReference):不管当前内存空间是否足够充足,都会回收它的内存。
4.虚引用(PhantomReference):虚引用必须和引用队列联合使用,用来判断垃圾回收的状态。
如何判断一个类是无用的类
1.该类所有的实例都已经被回收,也就是Java堆中不存在该类的任何实例
2.加载该类的ClassLoader已经被回收
3.该类对应的java.lang.Class对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法
不可达的对象并非非死不可
要真正宣告一个对象死亡,至少要经历两次标记过程,可达性分析法中不可达的对象被第一次标记并且进行一次筛选,筛选的条件是此对象是否有必要执行 finalize 方法。当对象没有覆盖 finalize 方法,或finalize方法已经被虚拟机调用过时,虚拟机将这两种情况视为没有必要执行。被判定为需要执行的对象将会被放在一个队列中进行第二次标记,除非这个对象与引用链上的任何一个对象建立关联,否则就会被真的回收。