剑指Offer(GC)——常见面试题

1、Object的finalize()方法是否与C++的析构函数一样

答案肯定是否定的,finalize调用是确定的而析构函数调用是不确定的。

一个Java方法经过第一次可达性分析时候发现没和GC Root相连,就去判断是否被finalize覆盖,如果被覆盖放进F-Queue队列中,然后JVM的finalize去回收这个方法。缺点是finalize覆盖的方法随时都可能会被终结而不是等到运行结束后,意义是给予对象最后一次重生的机会。

接下来验证一下,首先创建一个对象打印出来是没有问题的,手动触发gc会触发finalize方法,打印出Finalized,f是因为上面进行了赋值变成了null,finalization属性将该对象重新赋值最后打印出f地址。

出现的问题可能是:gc还没有执行完(finalize方法没有执行完成)就开始执行下面的程序,最后打印出的f.finalization就是null,这个时候需要加个sleep以保证gc完整执行完成。
在这里插入图片描述

2、Java中强引用、软引用、弱引用、虚引用之间的区别

(1)、强引用

是最普遍的一种引用,创建实例时经常使用的一种引用:

Object object = new Object();

最后即使可能会因为内存不足抛出OOM导致终止程序,也不会收回强引用产生的对象实例。若果想要回收强引用对象的实例需要将对象设置成null来弱化引用使其被回收。

(2)、软引用

是一种相对强引用弱一些的引用,只有当JVM内存不足的时候才会去回收软引用指向的对象。
JVM确定抛出OOM异常之前清理软引用指向的对象,软引用通常用来实现内存敏感的高速缓存,如果还有空闲的内存就会在暂时保留内存,内存不足时候清理掉这样保证了使用缓存同时不会耗尽内存。

String str = new String("abc");//强引用
SoftReference<String> softRef = new SoftReference<String>(str);//软引用

(3)、弱引用

相比起软引用还要弱一些,在GC的时候会被直接回收,但是由于GC线程执行优先级是比较低的因此回收的概率不是很大,适用于引用被偶尔引用但是不影响垃圾收集的对象。

String str = new String("abc");
WeakReference<String> wr = new WeakReference<String>(str);

(4)、虚引用

虚引用不会影响对象的生命周期会在任何时候都有可能被垃圾回收,主要作用是用于跟踪对象被垃圾回收器回收的活动,哨兵的作用,但是需要和ReferenceQueue联合起来使用。

String str = new String("abc");
ReferenceQueue queue = new ReferenceQueue();
PhantomReference ref = new PhantomReference(str,queue);

GC时候发现虚引用的情况,首先将其加入到引用队列中程序可以判断引用队列的对象就能判断这个对象是否被垃圾回收。
在这里插入图片描述
在这里插入图片描述

(5)、引用队列

是没有实际的存储结构,存储逻辑依赖于内部节点的关系来表达。
存储关联的且被GC的软引用,弱引用以及虚引用。

发布了242 篇原创文章 · 获赞 23 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_44240370/article/details/104076082