读书笔记-2java虚拟机的可达性算法与finalize方法

来源:互联网 发布:js复制文字到剪贴板 编辑:程序博客网 时间:2024/04/29 20:48
JAVA通过可达性分析算法来确定堆中哪些对象是应该被回收的。
很多人包括我以前在不了解的时候总以为是通过引用计数器来判断某个对象是否应该被回收但是后来想了想包括查阅一些资料发现不是这样的,因为如果采用引用计数器的方式没有办法解决循环引用的问题。
关于可达性分析算法,在jvm中有个GC Root Set ,里面有不确定个数的gc root 。可以作为gc root的对象有以下几种
1.虚拟机栈中的引用对象
2.方法区中类静态属性引用的对象
3.方法区中的常量引用的对象
4.本地方法栈中jni引用的对象

jvm就是通过这些gc root来判定对象是否还存活的,该算法的基本思想是通过一系列的gc root 做为起始点向下搜索,搜索走过的路径称为引用链,当一个对象到gc root没有任何引用链的时候,就说明该对象是不可引用的,此时不可被引用的对象便是可以回收的对象。
图中object5 6 7都是可以回收的

虽然是可以回收的,这里还涉及到了是否一定会被回收。
  1. 当对象无法与gc root相连时,判定对象是可以回收的
  2. 当对象被判定为可以回收的时候,判断其时候一定要被回收
  3. 在1,2两个条件满足的情况下,当对象没有覆盖finalize方法,或者finaze方法被执行过虚拟机将判定该对象没有必要执行finalize方法
  4. 如果被判定为没有必要执行finalize方法,那么将会把对象放到一个F-Queue(finalize queue :释放队列)中,最后将由虚拟机建立一个低优先级的finalizer线程去释放F-Queue中的对象
  5. 在释放过程中对象还可以完成一次自救,自救的方法就是让自己与gc root关联起来就可以了例如在对象的finalize方法中把自己也就是this赋值给一个一个其他对象的变量类型是当前对象的类型属性(但是如果这个其他对象也是在F-Queue中的就不能完成自救,原因就是这个其他对象本省并不能与gc root相关联),但是因为任何一个对象的finalizer方法只能由虚拟机执行一次,所以任何一个需要被回收的对象,也只能完成一次自救。
后记:
finalize这个方法建议大家平时不要用,这个方法完全是当时java诞生的时候为了照顾c++程序员做出的一种妥协,正常开发过程中完全可以忘记有这个方法。

作者:北京小明
QQ:645707787
Phone:18311276689
如果有哪里不正确的地方,欢迎指正。
1 1
原创粉丝点击