JAVA面试问到的四种引用

在JDK1.2版本之后,java对引用的概念进行了扩充,将引用分为强引用、软引用、弱引用和虚引用4种,4种引用强度依次逐次减弱。

强引用: 强引用指的是在程序代码之中普遍存在的,类似于"Object obj = new Object()"这类的引用,只要强引用还存在,垃圾回收器永远不会回收掉被引用的对象实例。

软引用: 在系统将要发生内存溢出之前,会把这些对象列入回收范围之中进行第二次回收。如果这次回收还是没有足够的内存,才会抛出内存溢出异常。在JDK1.2之后,提供了SoftReference类来实现软引用。

弱引用: 弱引用也是用来描述非必需对象的。但是它的强度要弱于软引用。被弱引用关联的对象只能生存到下一次垃圾回收发生之前。当垃圾回收器开始进行工作时,无论当前内存是否够用,都会回收掉只被弱引用关联的对象。在JDK1.2之后提供了WeakReference类来实现弱引用。

虚引用: 虚引用也被称为幽灵引用或者幻影引用,它是最弱的一种引用关系。一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用来取得一个对象实例。为一个对象设置虚引用的唯一目的就是能在这个对象被收集器回收时收到一个系统通知。在JDK1.2之后,提供了PhantomReference类来实现虚引用。

=====================================================================

理解部分

前言:

Java中提供四种引用类型的主要目的:

·可以让程序员通过代码的方式决定某些对象的生命周期

·有利于JVM进行垃圾回收

Java.lang.ref包下的引用类结构图

一、强引用

特点:GC时,永远不会被回收

是指创建一个对象并把这个对象赋给一个引用变量。比如:

Object obj = new Object();

String str = "Hello";

强引用有引用变量指向时永远不会被垃圾回收,JVM宁愿抛出OutOfMemory错误也不会回收这类对象。

public void fun1() {
    Object object = new Object();
    Object[] objArr = new Object[1000];
}

当运行至Object[] objArr = new Object[1000];这句时,如果内存不足,JVM会抛出OOM错误也不会回收object指向的对象。不过要注意的是当fun1运行完之后,object和objArr都已经不存在了,所以它们指向的对象都会被JVM回收。

如果想中断强引用和某个对象之间的关联,可以显示地将引用赋值为null,这样一来的话,JVM在合适的时间就会回收该对象。比如Vector类的clear方法中就是通过将引用赋值为null来实现清理工作

强引用也是导致内存泄露的主要原因

二、软引用

特点:内存不足时(自动触发GC),会被回收

如果一个对象具有软引用,内存空间足够,垃圾回收器就不会回收它;如果内存空间不足了,就会回收这些对象的内存。只要垃圾回收器没有回收它,该对象就可以被程序使用。软引用可用来实现内存敏感的高速缓存,比如网页缓存、图片缓存等。使用软引用可以防止内存泄露,增强程序的健壮性。

SoftReference的特点是它的一个实例保存对一个Java对象的软引用, 该软引用的存在不妨碍垃圾收集线程对该Java对象的回收。也就是说,一旦SoftReference保存了对一个Java对象的软引用后,在垃圾线程对这个Java对象回收前,SoftReference类所提供的get()方法返回Java对象的强引用。另外,一旦垃圾线程回收该Java对象之 后,get()方法将返回null。

示例:

JVM参数 -Xms10m -Xmx10m -XX:+PrintGCDetails

软引用是我们自己定义对象为为SoftReference类型的<Object>对象

上述示例说明:软引用在内存不够时,通过系统的GC,回收对象了

假设有一个应用需要读取大量的本地图片:

·如果每次读取图片都从硬盘上读取则会严重影响性能(频繁的IO操作)

·如果一次全部加载进内存又可能会导致内存溢出

此时使用软引用可以解决该问题

设计思路:用一个HashMap来保存图片的路径的相应图片对象关联的软引用之间的映射关系,在内存不足时,JVM会自动回收这些缓存图片对象所占用的空间,从而有效地避免OOM的问题。

Map<String, SoftRefrence<Bitmap>> imageCache = new HashMap<String, SoftRefrence<Bitmap>>();

三、弱引用

特点:无论内存是否充足,只要进行GC,都会被回收

弱引用也是用来面试非必须对象的,当JVM进行垃圾回收时,无论内存是否充足,都会回收弱引用相关的对象。在JAVA中,用java.lang.ref.WeakReference来表示:

示例:

上述示例表明:在内存充足的前提下,弱引用对象也被回收了

WeakHashMap的用法:

软应用和弱应用的使用场景:mybatis中的缓存

四、虚引用

特点:形同虚设,和没有引用没什么区别

虚引用和前面的软引用、弱引用不同,它并不影响对象的生命周期。在java中用java.lang.ref.PhantomReference类表示。如果一个对象与虚引用关联,则跟没有引用与之关联一样,在任何时候都可能被垃圾回收器回收。

要注意的是,虚引用必须和引用队列关联使用,当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会把这个虚引用加入到与之关联的引用队列中。程序可以通过判断引用队列中是否已经加入了虚引用,来了解被引用的对象是否将要被垃圾回收。如果程序发现某个虚引用已经被加入到引用队列,那么就可以在所引用的对象的内存被回收之前采取必要的行动。

示例:

虚引用的主要作用是跟踪对象被垃圾回收的状态。仅仅是提供了一种确保对象被finalize以后,做某些事情的机制。PhantomRefrence的get方法总是返回null,因此无法访问对应的引用对象。其意义在于说明一个对象已经进入finalization阶段,可以被GC回收,用来实现比finalization机制更灵活的回收操作。

换句话说,设置虚引用关联的唯一目的,就是在这个对象被收集器回收的时候收到一个系统通知或者后续添加进一步的处理。Java技术允许使用finalize()方法在垃圾收集器将对象从内存中清除之前做必要的清理工作。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值