美文网首页程序员Android开发经验谈Android开发
内存溢出、内存泄露和性能优化总结

内存溢出、内存泄露和性能优化总结

作者: chaychan | 来源:发表于2017-08-03 21:44 被阅读146次

内存溢出

内存溢出 out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;比如申请了一个Integer,但给它存了long才能存下的数,那就是内存溢出。

内存泄露

内存泄露 memory leak,是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光。memory leak会最终会导致out of memory!内存溢出就是你要求分配的内存超出了系统能给你的,系统不能满足需求,于是产生溢出。

Android中内存泄露优化的一些情况和建议

一、因静态变量没有释放而导致的内存泄露

场景:比如在Activity中,定义了一个静态变量,并在onCreate()中赋值,但是当Activity关闭后,没有将该静态变量置为null,导致其一直持有内存的应用。

public static MainActivity sInstance;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    sInstance = this;
}

建议:如果使用了静态变量,需要在没有用到的时候将其置为null,否则它会一直持有内存的引用,而虚拟机的内存是有限的,每个App分配的内存也很小,所以需要注意这些细节。上面情况是在Activity中创建了静态变量并赋值,但是在Activity关闭的时候没有将其置为null,需要在onDestroy()中将其置为null。

@Override
protected void onDestroy() {
    super.onDestroy();
    sInstance = null;
}

二、因使用无限播放的属性动画没有停止而导致的内存泄露

mIvIcon = (ImageView)findViewById(R.id.iv_icon);
ObjectAnimator rotationAnimation = ObjectAnimator.ofFloat(mIvIcon, "rotation", 0, 360);
rotationAnimation.setDuration(300);
rotationAnimation.setRepeatCount(ValueAnimator.INFINITE);
rotationAnimation.start();

以上代码为ImageView设置了旋转的属性动画,并且指定了动画执行次数为无限次,调用了start()方法开启动画。由于动画是无限播放动画,如果在Activity关闭后没有将其停止,尽管无法在界面上看到动画效果,Activity的View对象会被动画一直持有,无法释放,Activity由于被该View持有,所以也无法释放,最终会导致内存泄露。

建议:如果在Activity中使用了无限播放的动画,在Activity的onDestroy()中,需要调用animation.cancel()停止动画。

三、单例模式下忘记注销释放对象而导致的内存泄露

某些使用单例模式创建的类,有对应的registerListener()方法注册,使用的时候忘记调用其注销监听的方法unRegisterListener()方法,比如在registerListener(Context context)传入了上下文对象,在Activity如果使用到该单例模式创建的监听,如果Activity关闭的时候没有注销监听,一直持有Activity,此时Activity将无法被及时释放。

建议:当在Activity中使用单例模式创建的类时,记得注册监听和注销监听要成对使用,当没有用到的时候需要对其进行注销,防止内存泄露。

Android性能优化的一些建议

View的绘制

自定义View的时候,避免在onDraw()方法中执行大量操作,因为onDraw()方法可能会被频繁调用,此时不宜在onDraw()方法中创建新的局部对象,不然可能在一瞬间产生了大量的局部对象,会占用大量内存,影响程序的执行效率。

布局的优化

布局方面优化的建议,减少布局文件层级,删除无用的控件,这样系统在绘制的时候工作量少了,程序的性能便就提高了,如果布局中用LinearLayout或RelativeLayout实现,那么就用LinearLayout代替RelativeLayout,因为RelativeLayout的功能相对比较复杂,绘制的时候工作量较大,相对耗时较大。

使用线程池管理线程

使用线程池可以避免程序中存在大量的线程,线程池可以重用内部的线程,并且能有效控制线程的最大并发数,避免大量的线程因互相抢占系统资源而导致阻塞现象的发生,所以在开发中,我们要采用线程池来管理线程。

其他建议:

  • 常量使用static final修饰

  • 采用静态内部类

  • 对于不再需要使用的对象,显示的将其赋值为null,比如使用完Bitmap后先调用recycle(),再赋为null

  • 对于生命周期比Activity长的对象,如果需要应该使用ApplicationContext

相关文章

  • 内存优化

    内存优化主要是分析内存泄露和内存溢出。将从内存是怎么分配,内存怎么出现泄露和溢出,用工具判断什么情况出现泄露,找出...

  • 内存溢出、内存泄露和性能优化总结

    内存溢出 内存溢出 out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of...

  • 【内存】

    性能优化->虚拟机原理 怎么分析堆内存 内存泄露和内存溢出的原因 怎么做内存管理 JVM类加载机制Java内存区域...

  • 浅谈Android开发中的内存优化

    Android开发中,常常需要对App进行性能优化,这其中很重要的一点是进行内存优化,避免出现出内存泄露、内存溢出...

  • 性能优化系列文章(七) - 图片适配及其他情况

    前言 性能优化系列文章性能优化系列文章(一) - 内存泄露和内存抖动性能优化系列文章(二) - 自定义View代码...

  • Android内存优化-进阶

    内存优化-进阶篇 内存优化分为: 内存抖动、内存泄露、内存溢出 OOM 1、优秀的架构设计 1.1 MVVM 设计...

  • JAVA内存区域

    首先解释下内存溢出和内存泄露之间的区别,为后面的学习做些铺垫: 1、内存溢出和内存泄露的区别和联系 内存溢出 ou...

  • JAVA内存区域

    首先解释下内存溢出和内存泄露之间的区别,为后面的学习做些铺垫: 1、内存溢出和内存泄露的区别和联系 内存溢出 ou...

  • 基本性能优化

    布局优化 避免过度绘制嵌套,导致16秒无法完成绘制 使用viewstub提高布局性能 内存优化 避免内存溢出和内存...

  • 「性能优化4.1」内存优化的三个方面及工具

    内存优化的三个方面 APP 内存优化一般从 内存抖动,内存泄露,内存溢出这三个方面进行分析。 内存抖动 内存抖动是...

网友评论

    本文标题:内存溢出、内存泄露和性能优化总结

    本文链接:https://www.haomeiwen.com/subject/rldmlxtx.html