Android 内存泄漏

内存泄漏

1,使用adb命令:adb shell dumpsys meminfo 包名,查看当前activity数量

2,使用AS中Profiler进一步问题排查,点击Dump JAVA heap导出堆分配

常见内存泄漏的情况:

1、静态Activity(Activity上下文Context)和View

因为静态对象:context和textView的实例的生命周期和应用的生命一样,
而他们持有当前Activity的引用,一旦Activity销毁,
而他的引用一直持有,就不会被回收,所以产生内存泄漏了

2、单例造成的内存泄漏

单例的生命周期和应用的生命周期一样,也就是单例持有必须是和应用生命周期一样的对象,
不能持有和应用生命周期不一致的对象 ApplicationContext

3、线程造成的内存泄漏

匿名线程内部类会隐式引用Activity,当执行耗时任务时,一直隐式引用Activity,
当Activity关闭时,由于匿名线程内部类会隐式引用Activity无法及时回收

解决方法:

修改AsyncTask匿名内部类为静态类,解除Activity隐式引用,
Activity销毁时要及时取消异步任务staticAsyncTask.cancel(true),
防止异步任务执行完成更新销毁MemoryTestActivity实例的UI

4、非静态内部类创建静态实例造成的内存泄漏

解决方法:将该内部类设为静态内部类或将内部类抽象出来封装一个单例,
如果需要使用Context,请使用ApplicationContext

5、Handler造成的内存泄漏

解决方案总结:
在关闭Activity的时候停掉后台线程;线程停掉相当于切断了Handler和外部连接线,Activity自然会被在合适的时候回收;
如果Handler被delay延迟的Message持有了引用,那么使用相应的Handler的removeCallbacks()方法,把消息对象从消息队列移除就行;

将Handler声明为静态类
在Java中,非静态的内部类和匿名内部类都会隐式持有其外部类的引用,静态内部类不会持有外部类的引用。
静态类不持有外部类的对象,所以你的Activity可以随意被回收;由于Handler不在持有外部类的对象的引用,
导致程序不允许你在Handler中操作Activity中的对象了,所以你需要在Handler中增加一个对Activity的弱引用(WeakReference);

6、动画

在属性动画中有一类无限循环动画,如果在Activity中播放这类动画并且在onDestroy()中没有去停止动画,
那么动画会一直播放下去,这时候Activity会被View所持有,从而导致Activity无法被释放。
解决此类问题要在onDestroy()方法中去调用objectAnimator.cancel()来停止动画;

7、第三方库使用不当
1、对于EventBus,RxJava等一些第三方开源 框架 的使用,若是Activity销毁之前没有进行解除订阅会导致内存泄漏;
2、需要在生命周期相对注册与注销(onCreate->onDestory | onResume->onPause … )

8、资源未关闭造成的内存泄漏
对于使用了BraodcastReceiver,ContentObserver,File,Cursor,Stream,Bitmap等资源的使用,
应该在Activity销毁时及时关闭或者注销,否则这些资源将不会被回收,造成内存泄漏。

你可能感兴趣的:(android)