内存泄漏场景
Handler的错误使用
Handler是开发中异步处理最常使用到的工具之一,但是如果错误地使用Handler 也极容易产生内存泄漏。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21public class MainActivity extends AppCompatActivity {
private final Handler myHandler = new Handler(){
public void handleMessage(Message msg) {
//doSomething
}
};
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
myHandler.postDelayed(new Runnable() {
public void run() {
//doSomething
}
},60*10*1000);
}
}
怎么样,看起来是不是合情合理,但是其中隐藏着一个重要的隐患,当我们创建出一个Handler 的时候,代码中的mHandler为Handler 的非静态内部类的实例,所以mHandler 持有对外部类,即Activity 的引用。并且Handler 中的Looper不断轮询消息队列中的message,message 又持有mHandler的引用,但mHandler这玩意儿又持有Activity 的引用,所以这下倒好,因为你一个message 导致我整个Activity都无法被回收,你说气人不气人。
1 | public class MainActivity extends AppCompatActivity { |
资源没有及时关闭
在开发中,例如Cursor、File、IOStream等资源在使用后要及时进行关闭,避免造成内存的浪费。
TypedArray、Bitmap等要及时进行recycle
EventBus 、BroadcastReceiver注册后避免重复注册,使用后及时销毁
Java中的四中引用方式的区别
强引用
只要某个对象有强引用与之关联,JVM必定不会回收这个对象,即使在内存不足的情况下,JVM宁愿抛出OutOfMemory错误也不会回收这种对象。
软引用
软引用是用来描述一些有用但并不是必需的对象,在Java中用java.lang.ref.SoftReference类来表示。对于软引用关联着的对象,只有在内存不足的时候JVM才会回收该对象。因此,这一点可以很好地用来解决OOM的问题,并且这个特性很适合用来实现缓存:比如网页缓存、图片缓存等。
弱引用
弱引用也是用来描述非必需对象的,当JVM进行垃圾回收时,无论内存是否充足,都会回收被弱引用关联的对象。在java中,用java.lang.ref.WeakReference类来表示
虚引用
虚引用和前面的软引用、弱引用不同,它并不影响对象的生命周期。在java中用java.lang.ref.PhantomReference类表示。如果一个对象与虚引用关联,则跟没有引用与之关联一样,在任何时候都可能被垃圾回收器回收。
要注意的是,虚引用必须和引用队列关联使用,当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会把这个虚引用加入到与之 关联的引用队列中。程序可以通过判断引用队列中是否已经加入了虚引用,来了解被引用的对象是否将要被垃圾回收。如果程序发现某个虚引用已经被加入到引用队列,那么就可以在所引用的对象的内存被回收之前采取必要的行动。