Skip to content

Latest commit

 

History

History
58 lines (45 loc) · 3.36 KB

06.Android 内存泄漏的原因以及解决方案.md

File metadata and controls

58 lines (45 loc) · 3.36 KB

Android 内存泄漏的原因以及解决方案

参考答案
  1. 内存泄漏指对象不再使用,本该被回收,却因为有其他正在使用的对象持有该对象的引用,而无法被JVM回收

  2. 内存泄漏的影响:

    1. 应用可用内存减少,增加堆内存压力
    2. 频繁触发GC,会降低了应用的性能
    3. 到一定程序会导致内存溢出错误
  3. Android开发中常见内存泄漏及解决办法

    1. 静态变量生命周期与应用的生命周期一样,如果静态变量持有某个Activity的上下文,则对应Activity无法释放,导致内存泄漏(单例模式) 解决办法:使用Application的上下文
    2. 匿名内部类与非静态内部类因为都会持有外部类引用,当执行异步操作易导致内存泄漏 解决办法:将非静态内部类转为静态内部类+WeakReferenct的方式
    3. Handler消息队列存在延时消息导致内存泄漏 在onDestroy方法中调用Handler相应的方法移除回调和删除消息
    4. 各种注册的监听器忘记移除导致内存泄漏 解决办法:在onDestroy方法中取消注册
    5. 资源对象未关闭导致内存泄漏,如(IO,数据库,Bitmap等) 解决办法:及时关闭资源
    6. 属性动画未取消导致内存泄漏(如无限轮播图效果) 解决办法:onDestroy方法中取消动画
    7. 其他解决办法:使用AAC框架
  4. 内存泄漏排查工具: AS Monitor,MAT,LeakCanary

  5. 扩展: Java内存管理,GC

补充(统一格式:昵称 + 补充答案)
kuky:
  1. Handler引起的内存泄漏 原因:该线程持有Handler的引用,而Handler也持有Activity的引用,这就导致了Activity不再使用时,GC回收不了Activity 解决:Handler持有的引用最好使用弱引用,在Activity被释放的时候要记得清空Message,取消Handler对象的Runnable
  2. 单例模式引起的内存泄漏 原因:构建该单例的一个实例时需要传入一个Context,如果此时传入的是Activity,由于Context会被创建的实例一直持有,当Activity进入后台或者开启设置里面的不保留活动时,Activity会被销毁,但是单例持有它的Context引用,Activity没法销毁 解决:对于生命周期比Activity长的对象,要避免直接引用Activity的context,可以考虑使用ApplicationContext
  3. 非静态内部类创建静态实例引起的内存泄漏 原因:非静态的内部类会自动持有外部类的引用,创建的静态实例就会一直持有的引用 解决:可以考虑把内部类声明为静态的
  4. 非静态匿名内部类引起的内存泄漏 原因:如果匿名内部类被异步线程使用,可能会引起内存泄漏 解决:可以考虑把内部类声明为静态的
  5. 资源对象没有关闭引起的内存泄漏 原因:资源性对象比如Cursor、File、Bitmap、视频等,系统都用了一些缓冲技术,在使用这些资源之后没有关闭 解决:处理完资源对象的逻辑记得关闭,最好是形成习惯现写一开一关
  6. 集合对象没有及时清理引起的内存泄漏 原因:如果集合是static、不断的往里面添加东西、又忘记去清理,肯定会引起内存泄漏 解决:集合里面的东西、有加入就应该对应有相应的删除

不能通过 GC 来解决内存泄漏问题