四种类型

强引用(Strong Reference)

经常使用,内存不足,抛出OOM异常使程序异常终止。不会回收强引用对象来解决内存不足问题

软引用(Soft Reference)

当无强引用指向时,会在内存中停留一段时间。垃圾回收器根据JVM内存使用情况及SoftReference.get()调用情况决定是否对其回收

弱引用(Weak Reference)

只要垃圾回收器对其回收,无论内存使用情况如何,均回收(WeakReference.get()返回null)

虚引用 (Phantom Reference)

PhantomReference.get()永远返回null,因此无法通过get()获取目标对象的强引用从而使用对象

引用对列 (Reference Queue)

当检测到对象可达性变化后,垃圾回收器将已注册的引用对象添加到此队列中。一旦弱引用对象返回null,则该弱引用所指向的对象被标记为垃圾,弱引用对象变为无用。此时需进行清理工作,如WeakHashMap移除没用的条目来避免保存无限制增长的无意义的弱引用。

引用类型特性总结

引用类型

取得目标对象方式

垃圾回收条件

是否可能内存泄漏

强引用

直接调用

不回收

可能

软引用

通过 get() 方法

视内存情况回收

不可能

弱引用

通过 get() 方法

永远回收

不可能

虚引用

无法取得

不回收

可能

实例

SoftReference softReference = new SoftReference(buff);			//软引用
WeakReference weakReference = new WeakReference(buff);			//弱引用
ReferenceQueue<Object> refQueue = new ReferenceQueue<Object>();	 //引用队列
PhantomReference<Object> referent = new PhantomReference<>(new Object(), refQueue);	//虚引用
System.out.println(referent.get());	//null
System.gc();
System.runFinalization();

软引用获取Bitmap对象

//定义一个HashMap,保存软引用对象
Map<String, SoftReference<Bitmap>> imageCache = new HashMap<String, SoftReference<Bitmap>>();  
//添加软引用对象到缓存(imageCache)中
Bitmap bitmap = BitmapFactory.decodeFile(path);  
SoftReference<Bitmap> softBitmap = new SoftReference<Bitmap>(bitmap);  
imageCache.put(path, softBitmap);  
//从软引用中获取Bitmap对象
SoftReference<Bitmap> softBitmap = imageCache.get(path);  
if (softBitmap != null) {  
    Bitmap bitmap = softBitmap.get();       //通过get()获取软引用指向的对象
}

问题

为什么Android官方废弃SoftRefrerence软引用和WeakReference弱引用,而拥抱LruCache?

使用软引用时,在内存出时,无法决策是清除已存在的软引用还是申请增大内存。如果需要清除已存在的软引用,软引用间无优先级,无法决定先清除谁

LruCache可根据变量的使用频次来决定先清除谁

GC判断为垃圾的对象一定会回收吗

不会,需要两次标记。
第一次标记并筛选,筛选出对象是否要执行finalize,如果对象没有重写finalize方法,或者finalize已被虚拟机调用过,就是没有必要执行,直接回收
如果不是上述情况,则有必要执行finalize,则GC将对象放在F-Queue对象,由Finializer线程执行finalize

强引用置为null,会不会被回收?

不会立即被回收,置为null后,只是将此对象的"根去除掉"。概念参照GC回收算法。
静态 类型变量必须及时赋值为null,否则其生命周期与应用程序一致