Android app 内存泄漏分析

一、基础知识
1.1、内存泄露、内存溢出:

内存泄露(Memory Leak)指一个无用对象持续占有内存或无用对象的内存得不到及时的释放,从而造成内存空间的浪费
例如,当Activity的onDestroy()方法被调用以后,Activity 本身以及它涉及到的 View、Bitmap等都应该被回收。但是,如果有一个后台线程持有对这个Activity的引用,那么Activity占据的内存就不能被回收,严重时将导致OOM,最终Crash。
内存溢出(Out Of Memory)指一个应用在申请内存时,没有足够的内存空间供其使用

相同点:都会导致应用运行出现问题、性能下降或崩溃。
不同点:

内存泄露是导致内存溢出的原因之一,内存泄露严重时将导致内存溢出
内存泄露是由于软件设计缺陷引起的,可以通过完善代码来避免;内存溢出可以通过调整配置来减少发生频率,但无法彻底避免

1.2、Java 的内存分配:

静态存储区:在程序整个运行期间都存在,编译时就分配好空间,主要用于存放静态数据和常量
栈区:当一个方法被执行时会在栈区内存中创建方法体内部的局部变量,方法结束后自动释放内存
堆区:通常存放 new 出来的对象,由 Java 垃圾回收器回收

1.3、四种引用类型:

强引用(StrongReference):Jvm宁可抛出 OOM (内存溢出)也不会让 GC(垃圾回收) 回收具有强引用的对象
软引用(SoftReference):只有在内存空间不足时才会被回收的对象
弱引用(WeakReference):在 GC 时,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存
虚引用(PhantomReference):任何时候都可以被GC回收,当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之关联的引用队列中。程序可以通过判断引用队列中是否存在该对象的虚引用,来了解这个对象是否将要被回收。可以用来作为GC回收Object的标志。

内存泄漏就是指new出来的Object(强引用)无法被GC回收
1.4、非静态内部类和匿名类:

非静态内部类和匿名类会隐式地持有一个外部类的引用
1.5、静态内部类:

外部类不管有多少个实例,都是共享同一个静态内部类,因此静态内部类不会持有外部类的引用
二、内存泄漏情况分析
2.1、资源未关闭

在使用Cursor,InputStream/OutputStream,File的过程中往往都用到了缓冲,因此在不需要使用的时候就要及时关闭它们,以便及时回收内存。它们的缓冲不仅存在于 java虚拟机内,也存在于java虚拟机外,如果只是把引用设置为null而不关闭它们,往往会造成内存泄漏。
此外,对于需要注册的资源也要记得解除注册,例如:BroadcastReceiver。动画也要在界面不再对用户可见时停止。
2.2、Handler

在如下代码中

public class HandlerActivity extends AppCompatActivity {

private Handler handler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
    }
};

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_handler);
}

}

在声明Handler对象后,IDE会给开发者一个提示:

This Handler class should be static or leaks might occur.

意思是:Handler需要声明为static类型的,否则可能产生内存泄漏

这里来进行具体原因分析:
应用在第一次启动时, 系统会在主线程创建Looper对象,Looper实现了一个简单的消息队列,用来循环处理Message。所有主要的应用层事件(例如Activity的生命周期方法回调、Button点击事件等)都会包含在Message里,系统会把Message添加到Looper中,然后Lo

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

安卓兼职framework应用工程师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值