不同的引用类型,主要体现的是对象不同的可达性状态和对垃圾收集的影响。
强引用:是我们常见的普通对象引用。只要还有强引用指向一个对象,就能表明对象还活着,垃圾回收器不会进行回收。
软引用:是一种相对强引用弱化一些的引用,可以让对象豁免一些垃圾收集。只有当jvm认为内存不足时,才会去试图回收软引用指向的对象。jvm会确保在抛出outofmemoryError之前,清理软引用对象。如果还有空闲内存就不会清理。
弱引用:弱引用并不能使对象豁免垃圾收集,仅仅是提供一种访问弱引用状态下的对象途径。这就可以用来构建一种没有特定约束的关系,比如,维护一种非强制性的映射关系,如果试图获取时对象还在,就使用它,否则重现实例化。这是很多缓存实现的选择。垃圾回收一旦发现弱引用对象,不管内存是否足够都会进行回收。
幻象引用:仅仅是提供了一种确保对象被finalize以后,做某些事情的机制。
比如:通常用来做所谓的Post-Mortem清理机制。
使用实例:
程序设计中一般很少使用弱引用与虚引用,使用软用的情况较多,这是因为软引用可以加速JVM对垃圾内存的回收速度,可以维护系统的运行安全,防止内存溢出(OutOfMemory)等问题的产生。
应用场景:
假设我们的应用会用到大量的默认图片,比如应用中有默认的头像,默认游戏图标等等,这些图片很多地方会用到。如果每次都去读取图片,由于读取文件需要硬件操作,速度较慢,会导致性能较低。所以我们考虑将图片缓存起来,需要的时候直接从内存中读取。但是,由于图片占用内存空间比较大,缓存很多图片需要很多的内存,就可能比较容易发生OutOfMemory异常。这时,我们可以考虑使用软引用技术来避免这个问题发生。
首先定义一个HashMap,保存软引用对象。
private Map<String, SoftReference<Bitmap>> imageCache = new HashMap<String, SoftReference<Bitmap>>();
再来定义一个方法,保存Bitmap的软引用到HashMap。
public void addBitmapToCache(String path) {
// 强引用的Bitmap对象
Bitmap bitmap = BitmapFactory.decodeFile(path);
// 软引用的Bitmap对象
SoftReference<Bitmap> softBitmap = new SoftReference<Bitmap>(bitmap);
// 添加该对象到Map中使其缓存
imageCache.put(path, softBitmap);
}
获取的时候,可以通过SoftReference的get()方法得到Bitmap对象。
public Bitmap getBitmapByPath(String path) {
// 从缓存中取软引用的Bitmap对象
SoftReference<Bitmap> softBitmap = imageCache.get(path);
// 判断是否存在软引用
if (softBitmap == null) {
return null;
}
// 取出Bitmap对象,如果由于内存不足Bitmap被回收,将取得空
Bitmap bitmap = softBitmap.get();
return bitmap;
}