问题:Object的finaliz()方法 的作用是否与C++的析构函数作用相同?
---》不同的
1、C++的析构函数调用确定,就是对象离开作用域之后就马上被删除。而java Object的finaliz()调用之后,具有不确定性。
2、将未被引用的对象放置于F-Queue队列(当垃圾回收器要宣告一个对象要死亡的时候,至少要经过2次标记过程,如果对象经过了可达性分析算法之后,发现没有跟GC ROOT有相连的引用链,就被会第一次标记,并判断是否执行finaliz方法,如果 对象覆盖了finaliz方法,且未被引用过,那这个对象就会被放置在F-Queue队列中,并在等一段时间后由虚拟机自动建立的低优先级的finaliz线程去执行这个finaliz方法)
3、方法执行随时可能会被终止
4、给予对象最后一次重生的机会
public class Finalization {
public static Finalization finalization;
@Override
protected void finalize(){
System.out.println("Finalized");
finalization = this; // 这里是将f之前引用的对象赋值给finalization
} public static void main(String[] args) {
Finalization f = new Finalization();
System.out.println("First print: " + f);
f = null;
System.gc();
try {// 休息一段时间,让上面的垃圾回收线程执行完成
Thread.currentThread().sleep(1000);
} catch (InterruptedException e){
e.printStackTrace();
}
System.out.println("Second print: " + f);
System.out.println(f.finalization);
}
}
不建议使用finalize方法,因为gc回收之前会调用finalize方法,而gc回收时间是不确定的,导致finalize方法的调用时间不确定。
问题:Java中额强引用,软引用,弱引用,虚引用,有什么用?(注意着是引用,不是对象)
----》
强引用:最普遍的引用 :Object obj = new Object()
抛出OutOfMemoryError终止程序也不会回收具有强引用的对象
通过将对象设置为null来弱化引用,使其被回收
问什么时候会回收这个强引用呢?---》1、程序停止了,2、设置为null,3、他的对象超出了生命周期的范围
软引用:对象处于有用但是非必须的状态
只有当内存空间不足时,GC会回收该引用的对象的内存
可以用来实现高速缓存
String str = new String("avc"); // 强引用
SoftReference<String> softRef = new SoftReference<String>(str); // 软引用
弱引用:非必须的对象,比软引用更弱一些
GC时会被回收,无论当前内存是否足够,一看到弱引用的对象,就马上回收
被回收的概率也不大,因为GC线程优先级比较低
适用于引用偶尔被使用且不影响垃圾收集的对象
String str = new String("abc");
WeekReference<String> abcWeekRef = new WeakReference<>();
虚引用:不会决定对象的生命周期
任何时候都可能被垃圾回收器回收
跟踪对象被垃圾收集器回收的活动,起哨兵作用
必须和引用队列ReferenceQueue联合使用
问:虚引用和弱引用有什么区别?---》虚引用一定和ReferenceQueue配合使用
String str = new Strin("abc");
ReferenceQueue queue = new ReferenceQueue();
PhantomReference ref = new PhantomReference(Str , queue);
Gc在回收对象,如果发现对象有虚引用,那么在回收之前,则将对象的虚引用放入到与之关联的引用队列中,那么我们可以判断引用队列中是否加入了元素,则知道虚引用是否将要被回收,起到了一个哨兵的作用。
引用队列
无实际存储结构,存储逻辑依赖于内部节点之间的关系来表达
存储关联的且被GC的软引用,弱引用以及虚引用
核心:当对象的引用是软引用,弱引用,虚引用的时候,当引用对象指向的对象被回收之后,引用对象会被加入到ReferenceQueue中!!!作者用了一整个篇幅来说明这个问题!