1.引用计数算法
给对象添加一个引用计数器,当有一个地方引用它时,计数器就加一;当引用失效时,就减一;任何时刻计数器为0的对象都是不可能再被使用的。
缺点:不能解决相互循环引用的问题。 当两个对象相互引用时,无法回收。
Python使用的是引用计数算法。Java不是。
2.可达性分析算法
Java、C#、Lisp所使用的
通过一系列的GC Roots的对象作为起点,从这些节点开始向下搜索,搜索走过的路径称为引用链,当一个对象到GC Roots没有任何引用链相连(即从GC Roots到这个对象不可达)时,证明此对象不可用。
可以作为GC Roots的对象:
- 虚拟机栈中引用的对象
- 方法区中类静态属性引用的对象
- 方法区中常量引用的对象
- 本地方法栈中JNI引用的对象
强引用、软引用、弱引用、虚引用
finalize方法:
- 只会执行一次
- 如果没有finalize方法或已经执行过finalize方法,JVM会将此种情况视为没必要执行finalize方法
- 如果有必要执行,会将此对象放在JVM建立的、低优先级Finalizer线程去执行finalize方法。
- 所谓的执行指触发这个方法,但并不承诺会等待它运行完毕。(考虑到死循环或执行缓慢的极端情况,如果不这样可能会永久等待)
- finalize方法中,如果将自己与引用链某一个对象关联上,那么这个对象会逃过一劫。但这个对象再次回收时,不会执行finalize方法,直接释放对象。
注:
1、不要在finalize方法中将对象与引用链的对象关联上
2、不要在finalize方法中释放资源,尽量使用try-finally块