判断对象是否可以回收
1.引用计数法
-
解释:
根据引用这个对象的数量来判断对象是不是有用的,cnt>0,对象时有用的, cnt=0,对象是无用的,可以回收。 -
缺点:
可能会造成循环引用的问题。
2.可达性分析(类似于树)
-
解释:
如果一个对象是gc roots 可以通过链路找到的,那么这个对象就是有用的, 如果gc roots 不可达,那么对象就是没用的,可以被回收。 -
优点:
不会出现循环引用的问题 -
什么可以作为gc roots?
1. JNI(Java native interface)中的静态对象 2. 虚拟机栈中引用的对象 3. 方法区中类静态属性引用的对象 4. 方法区常量引用的对象 -
原因
参考https://blog.csdn.net/qq_41895761/article/details/87454607 -
finalize()方法
finalize是对象的自救方法,如果一个对象被gc roots 不可达,这个时候对象不一定会被回收,可以通过finalize()自救。
一个对象只能执行一次finalize()方法,然后finalize()不建议,因为finalize()“运行代价高昂,有很大的不确定性”
真正判断一个对象死亡,必须经过两次标记.
在第一次可达性分析判断不可达之后,虚拟机会判断对象是否有必要使用finalize()方法实现自救。
在第一次被判断无用之后,虚拟机会对无用的对象进行二次扫描,这个时候对象就被回收。如果对象成功调用了finalize(),那么对象会和gc roots重新建立通路,可达,二次扫描就不会被回收
-
如何判断对象是否需要finalize()方法?
如果对象没有覆盖finalize() 或者是虚拟机已经执行过finalize() 那么虚拟机就判断这个对象“没有必要finalize” -
虚拟机是如何执行finalize()?
《java虚拟机》page 87
对象引用分类
引用为什么要分类?
对于某种对象,我们希望内存足够时就保留它,内存不够时,就清理掉它(好像备胎啊)
-
强引用
A a = new A()创建的对象,当引用存在时,一般不会清理它。 -
软引用
软引用:有用但是不是必须,如果即将发生内存溢出的话,回收这些软引用, 此时内存还是不够的话,就会有内存溢出 -
弱引用
弱引用:非必须,对象只能存活到下一次gc之前,不会考虑内存是否够用。 -
虚引用
虚引用:幽灵引用这个引用存在的目的在于让对象被回收时可以收到系统通知,对于对象的生存没有影响,也无法获得对象实例。
《Java虚拟机》 今日感悟:我爱《Java虚拟机》,比昨天更爱他