• 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销毁时及时关闭或者注销,否则这些资源将不会被回收,造成内存泄漏。

  • 相关阅读:
    Java学习【String类详解】
    快鲸scrm:助力企业快速破解“无效私域”难题
    mediasoup学习与实践
    Solidity智能合约开发 — 4.3-合约的事件和继承
    蓝桥杯STM32G431RBT6实现按键的单击、双击、长按的识别
    04_数据库
    DDD--战略设计和战术设计
    [自定义 Vue 组件] 小尾巴 Logo 组件 TailLogo
    包管理器pacman常用方法
    快递100使用
  • 原文地址:https://blog.csdn.net/weixin_41940961/article/details/134402148