专栏名称: 安卓开发精选
伯乐在线旗下账号,分享安卓应用相关内容,包括:安卓应用开发、设计和动态等。
目录
相关文章推荐
开发者全社区  ·  腾讯地图+deepseek翻车了...... ·  16 小时前  
开发者全社区  ·  字节CEO全员会反思DeepSeek影响 ·  昨天  
开发者全社区  ·  突发:DeepSeek被封杀 ·  2 天前  
开发者全社区  ·  又有北大金硕女转行教培了 ·  2 天前  
开发者全社区  ·  邻家弟弟好厉害 ·  3 天前  
51好读  ›  专栏  ›  安卓开发精选

Android性能优化之内存泄漏

安卓开发精选  · 公众号  · android  · 2016-12-21 20:49

正文

(点击 上方公众号 ,可快速关注)


来源: 无嘴小呆子

链接: blog.csdn.net/ljd2038/article/details/53560829


综述


内存泄漏(memory leak)是指由于疏忽或错误造成程序未能释放已经不再使用的内存。那么在Android中,当一个对象持有Activity的引用,如果该对象不能被系统回收,那么当这个Activity不再使用时,这个Activity也不会被系统回收,那这么以来便出现了内存泄漏的情况。在应用中内出现一次两次的内存泄漏获取不会出现什么影响,但是在应用长时间使用以后,若是存在大量的Activity无法被GC回收的话,最终会导致OOM的出现。那么我们在这就来分析一下导致内存泄漏的常见因素并且如何去检测内存泄漏。


导致内存泄漏的常见因素


情景一:静态Activity和View


静态变量Activity和View会导致内存泄漏,在下面这段代码中对Activity的Context和TextView设置为静态对象,从而产生内存泄漏。


import android . content . Context ;

import android . support . v7 . app . AppCompatActivity ;

import android . os . Bundle ;

import android . widget . TextView ;

public class MainActivity extends AppCompatActivity {

private static Context context ;

private static TextView textView ;

@Override

protected void onCreate ( Bundle savedInstanceState ) {

super . onCreate ( savedInstanceState );

setContentView ( R . layout . activity_main );

context = this ;

textView = new TextView ( this );

}

}


情景二:Thread,匿名类,内部类


在下面这段代码中存在一个非静态的匿名类对象Thread,会隐式持有一个外部类的引用LeakActivity,从而导致内存泄漏。同理,若是这个Thread作为LeakActivity的内部类而不是匿名内部类,他同样会持有外部类的引用而导致内存泄漏。在这里只需要将为Thread匿名类定义成静态的内部类即可(静态的内部类不会持有外部类的一个隐式引用)。


public class LeakActivity extends AppCompatActivity {

@Override

protected void onCreate ( Bundle savedInstanceState ) {

super . onCreate ( savedInstanceState );

setContentView ( R . layout . activity_leak );

leakFun ();

}

private void leakFun (){

new Thread ( new Runnable () {

@Override

public void run () {

try {

Thread . sleep ( Integer . MAX_VALUE );

} catch ( InterruptedException e ) {

e . printStackTrace ();

}

}

});

}

}


情景三:动画


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


public class LeakActivity extends AppCompatActivity {

private TextView textView ;

@Override

protected void onCreate ( Bundle savedInstanceState ) {

super . onCreate ( savedInstanceState );

setContentView ( R . layout . activity_leak );

textView = ( TextView ) findViewById ( R . id . text_view );

ObjectAnimator objectAnimator = ObjectAnimator . ofFloat ( textView , "rotation" , 0 , 360 );

objectAnimator . setRepeatCount ( ValueAnimator . INFINITE );

objectAnimator . start ();

}

}


情景四:Handler


对于Handler的内存泄漏在(Android的消息机制——Handler的工作过程)[http://blog.csdn.net/ljd2038/article/details/50889754]这篇文章中已经详细介绍,就不在赘述。


情景五:第三方库使用不当


对于EventBus,RxJava等一些第三开源框架的使用,若是在Activity销毁之前没有进行解除订阅将会导致内存泄漏。


使用MAT检测内存泄漏


对于常见的内存泄露进行介绍完以后,在这里再看一下使用MAT(Memory Analysis Tool)来检测内存泄露。MAT的下载地址为:http://www.eclipse.org/mat/downloads.php。

下面来看一段会导致内存泄露的错误代码。


public class LeakActivity







请到「今天看啥」查看全文


推荐文章
开发者全社区  ·  腾讯地图+deepseek翻车了......
16 小时前
开发者全社区  ·  字节CEO全员会反思DeepSeek影响
昨天
开发者全社区  ·  突发:DeepSeek被封杀
2 天前
开发者全社区  ·  又有北大金硕女转行教培了
2 天前
开发者全社区  ·  邻家弟弟好厉害
3 天前
海蓝博士  ·  痛苦,是关系走向稳定、深入之门
7 年前