一 、简介
当一个对象仅仅被SoftReference或WeakReference指向, 而没有任何其他StrongReference指向的时候, 如果内存不足或GC回收, 那么这个对象就会被回收. WeakReference的基本是:
SoftReference<MainActivity> softReference = null;
WeakReference<MainActivity> weakReference = new WeakReference(MainActivity)(activity);
当要获得weak reference引用的object时, 首先需要判断它是否已经被回收:
weakReference .get();
内存吃紧,系统开始会GC。这次GC后,weakReference .get()是返回null,说明在系统内存紧张的情况下,软引用被回收。
使用软引用以后,在OutOfMemory异常发生之前,这些缓存的资源的内存空间可以被释放掉的,从而避免内存达到上限,避免Crash发生。
需要注意的是,在垃圾回收器对这个Java对象回收前,SoftReference类所提供的get方法会返回Java对象的强引用,一旦垃圾线程回收该Java对象之后,get方法将返回null。所以在获取软引用对象的代码中,一定要判断是否为null,以免出现NullPointerException异常导致应用崩溃。
二、运用场景
handler的使用防止内存泄露
public class MainActivity extends AppCompatActivity {
private MyHandler mHandler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mHandler = new MyHandler(this);
new Thread(new MyRunnable()).start();
}
//防止Handler造成的内存泄漏
private static class MyHandler extends Handler{
private SoftReference<MainActivity> softReference;
private MyHandler(MainActivity activity){
softReference = new SoftReference<MainActivity>(activity);
}
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if(softReference.get() != null){
switch (msg.what){
//更新UI
}
}
}
}
private class MyRunnable implements Runnable{
@Override
public void run() {
mHandler.sendEmptyMessage(10);
}
}
}
三、总结
在Android应用的开发中,为了防止内存溢出,在处理一些占用内存大而且声明周期较长的对象时候,可以尽量应用软引用和弱引用技术。软引用,弱引用都非常适合来保存那些可有可无的缓存数据。如果这样做,当系统内存不足时,这些缓存数据会被回收,不会导致内存溢出。而当内存资源充足时,这些缓存数据又可以存在相当长的时间。
笔者认为,如果只是想避免OutOfMemory异常的发生,则可以使用软引用。如果对于应用的性能更在意,想尽快回收一些占用内存比较大的对象,则可以使用弱引用。还有就是可以根据对象是否经常使用来判断。如果该对象可能会经常使用的,就尽量用软引用。如果该对象不被使用的可能性更大些,就可以用弱引用。