引用计数算法(无法解决循环引用)
可达性分析算法
可以作为GC Root的对象:
1.虚拟机栈中引用的对象(方法堆栈中的参数,局部变量,临时变量)
2.方法区类中静态属性引用的对象
3.方法区中常量引用的对象
4.本地方法栈中JNI引用的对象
5.同步锁持有的对象
引用
1.强引用
2.软引用(内存溢出之前,会进行第二次回收,如果内存还不够才抛出内存溢出异常)
3.弱引用(只生存到下一次垃圾回收前为止)
4.虚引用
生存还是死亡
finalize() 对象覆盖该方法,并且没有执行过,会放入一个F-Queue队列。低优先级异步线程执行(只要重新与引用链上的任何一个对象建立关联,从即将回收的集合中逃脱)。
回收方法区(难点)
判定一个常量是否“废弃”还是相对简单,而要判定一个类型是否属于“不再被使用的类”的条件就
比较苛刻了。需要同时满足下面三个条件:
1.该类所有的实例都已经被回收,也就是Java堆中不存在该类及其任何派生子类的实例。
2.加载该类的类加载器已经被回收,这个条件除非是经过精心设计的可替换类加载器的场景, 如OSGi、JSP的重加载等,否则通常是很难达成的。
3.该类对应的java.lang.Class对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法。
在大量使用反射、动态代理、CGLib等字节码框架,动态生成JSP以及OSGi这类频繁自定义类加载器的场景中,通常都需要Java虚拟机具备类型卸载的能力,以保证不会对方法区造成过大的内存压力。