咱们知道在Java中除了基础的数据类型之外,其它的都为引用类型。 而Java根据其生命周期的长短将引用类型又分为强引用、软引用、弱引用、幻象引用 。面试
正常状况下咱们平时基本上咱们只用到强引用类型,而其余的引用类型咱们也就在面试中,或者平日阅读类库或其余框架源码的时候才能见到。缓存
咱们平日里面的用到的new了一个对象就是强引用,例如 Object obj = new Object();
当JVM的内存空间不足时,宁愿抛出OutOfMemoryError使得程序异常终止也不肯意回收具备强引用的存活着的对象!bash
记住是存活着,不多是你new一个对象就永远不会被GC回收。当一个普通对象没有其余引用关系,只要超过了引用的做用域或者显示的将引用赋值为null时,你的对象就代表不是存活着,这样就会能够被GC回收了。固然回收的时间是不必定的具体得看GC回收策略。框架
软引用的生命周期比强引用短一些。软引用是经过SoftReference
类实现的。分布式
Object obj = new Object();
SoftReference softObj = new SoftReference(obj);
obj = null; //去除强引用
复制代码
这样就是一个简单的软引用使用方法。经过get()
方法获取对象。当JVM认为内存空间不足时,就回去试图回收软引用指向的对象,也就是说在JVM抛出OutOfMemoryError
以前,会去清理软引用对象。软引用能够与引用队列(ReferenceQueue)
联合使用。函数
Object obj = new Object();
ReferenceQueue queue = new ReferenceQueue();
SoftReference softObj = new SoftReference(obj,queue);
obj = null; //去除强引用
复制代码
当softObj
软引用的obj
被GC回收以后,softObj
对象就会被塞到queue
中,以后咱们能够经过这个队列的poll()
来检查你关心的对象是否被回收了,若是队列为空,就返回一个null
。反之就返回软引用对象也就是softObj
。性能
软引用通常用来实现内存敏感的缓存,若是有空闲内存就能够保留缓存,当内存不足时就清理掉,这样就保证使用缓存的同时不会耗尽内存。例如图片缓存框架中缓存图片就是经过软引用的。spa
弱引用是经过WeakReference
类实现的,它的生命周期比软引用还要短,也是经过get()
方法获取对象。code
Object obj = new Object();
WeakReference<Object> weakObj = new WeakReference<Object>(obj);
obj = null; //去除强引用
复制代码
在GC的时候,无论内存空间足不足都会回收这个对象,一样也能够配合ReferenceQueue
使用,也一样适用于内存敏感的缓存。ThreadLocal
中的key就用到了弱引用。对象
也称虚引用,是经过PhantomReference
类实现的。任什么时候候可能被GC回收,就像没有引用同样。
Object obj = new Object();
ReferenceQueue queue = new ReferenceQueue();
PhantomReference<Object> phantomObj = new PhantomReference<Object>(obj , queue);
obj = null; //去除强引用
复制代码
没法经过虚引用访问对象的任何属性或者函数。那就要问了要它有什么用?虚引用仅仅只是提供了一种确保对象被finalize
之后来作某些事情的机制。好比说这个对象被回收以后发一个系统通知啊啥的。虚引用是必须配合ReferenceQueue
使用的,具体使用方法和上面提到软引用的同样。主要用来跟踪对象被垃圾回收的活动。
若有错误欢迎指正!
我的公众号:yes的练级攻略
有相关面试进阶(分布式、性能调优、经典书籍pdf)资料等待领取