强引用
强引用只有在引用没有人指向,为null时会被垃圾回收。当jvm内存不足的时候,宁愿抛出内存溢出的异常,也不会随便回收他们
软引用
软引用只要在jvm内存不足的情况会回收。如果内存空间足够就不会进行回收他们。软引用可以用来做高速缓存。
一般配置有相应的队列。软引用回收的时候,会把软引用放在队列里面。可以从队列取出软引用
使用场景
图片缓存。图片缓存框架中,“内存缓存”中的图片是以这种引用保存,使得 JVM 在发生 OOM 之前,可以回收这部分缓存。
网页缓存。
弱引用
在垃圾回收发生的区域,只要扫描到有弱引用,不管内存是不是足够就会进行回收。
但是,垃圾收集器线程是一个优先级很低的线程,所以不一定会扫描到。弱引用有可以放到队列,同软引用。但是比软引用有更短的生命周期
使用场景
一个类持有另一个类的引用时,常用。
一个类发送网络请求,承担 callback 的静态内部类,则常以虚引用的方式来保存外部类的引用
虚引用
虚引用的对象,如同没有引用指向。并不能控制对象的生命周期。任何时候都可以发生垃圾回收。
虚引用主要用来跟踪垃圾回收的活动,
并且他的使用必须和引用队列联合使用。当垃圾收集器回收一个对象时,发现他是虚引用,回收前会把他加入到引用队列,在进行回收。
程序判断一个对象有没有被回收,就可以通过,引用队列里面有没有虚引用。可以在所引用的对象的内存被回收之前采取必要的行动。
使用场景:
可以用来跟踪对象呗垃圾回收的活动。一般可以通过虚引用达到回收一些非java内的一些资源比如堆外内存的行为。例如:在 DirectByteBuffer 中,会创建一个 PhantomReference 的子类Cleaner的虚引用实例用来引用该 DirectByteBuffer 实例,Cleaner 创建时会添加一个 Runnable 实例,当被引用的 DirectByteBuffer 对象不可达被垃圾回收时,将会执行 Cleaner 实例内部的 Runnable 实例的 run 方法,用来回收堆外资源。