剑指Offer(GC)——面试题

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

答案是不同的,因为析构函数的调用是确定的,而finalize是不确定的,假如一个java的方法,经历过第一次可达性分析的时候,发现并没有和GC ROOTS相连,那么就会去判断是否被finalize覆盖,如果是,就会被放进F-Queue队列中,最后由JVM的finalize去回收这个方法。缺点就是finalize覆盖的方法随时都有可能会被终结,而不是一定等运行结束后,但是意义在于可以给一个方法一次逃脱被回收的机会。

写一个程序来验证一下:

程序思路是:首先我们new 一个对象,然后打印出来,是没问题的。然后我们手动触发gc,gc触发finalize方法,此时打印出Finalized,而f因为我们上面进行了赋值,所以变成了null,但是finalization的这个属性,又将该对象重新赋值回去,于是最后打印出f的地址。

但是问题在于刚才说的,有可能gc还没执行完(也就是说finalize方法还没执行完),就执行下面的程序了,那么最后一个打印的f.finalization就会是null,这是我们不想看见的,所以我们可以加一个sleep,保证gc完整执行

在这里插入图片描述

  1. Java中的强引用,软引用,弱引用,虚引用有什么作用?
  • 强引用

最普遍的引用

Object obj = new Object();

最后就算因为内存不足,抛出oom终止程序,也不会因此而回收强引用产生的对象实例。如果我们想回收强引用的对象,就需要将对象设置为null来弱化引用,使其被回收。

  • 软引用

是一种相对强引用弱化一些的引用,可以让对象豁免一些垃圾收集,只有当JVM认为内存不足时,才会去试图回收软引用指向的对象。JVM会确保在抛 出OutOfMemoryError之前,清理软引用指向的对象。软引用通常用来实现内存敏感的缓存,如果还有空闲内存,就可以暂时保留缓存,当内存不足时清理掉,这样就保证了使用缓存的同时,不会耗尽内存。

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

比软引用的声明更加弱,在GC的时候,不管内存缺不缺都会被直接回收,但是由于GC线程的执行优先级比较低,所以被回收的概率也不是很高,适用于引用偶尔被使用,但是不影响垃圾收集的对象。

String str = new String("abc");
WeakReference<String> wr = new WeakReference<String>(str);
  • 虚引用

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

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

在GC的时候,如果发现了有虚引用的情况,会首先将其加入到引用队列中,程序可以判断引用队列的对象就能判断这个对象是否被垃圾回收了。

在这里插入图片描述

在这里插入图片描述

  • 引用队列(ReferenceQueue)

没有实际的存储结构,但是可以理解成链表,它的存储依赖于内部节点之间的关系来表达,就像是leetcode的题,next连接node。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值