android 内存溢出OOM问题

好久没有进cnblogs了,都快长草了.之前对接某度要求我司的插件 monkey test满8小时无OOM 无crash 虐哭了...各种OOM 下面把当时写的一篇笔记po上来防止长草.

1.什么是OOM,为什么会有OOM

Android主要应用在嵌入式设备中,所以因为嵌入式设备本身的一些限制,通常内存都会比较有限.JAVA拥有自己的一套垃圾回收机制,但并不是说用java编写的程序就不会程序溢出.java运行在虚拟机中,虚拟机在初始化时会给它的对内存(Heap)设置一个上限值,android中这个上限值一般是16m.当因为代码缺陷导致内存泄露,泄露的内存被一些数据对象占用着,无法通过GC去回收释放,最终就会导致OOM.

2.怎样检查项目中是否有OOM问题

要检查项目中是否有OOM问题,可以借助eclipse中的DDMS和MAT去分析观察内存.我们可以这样做:

1)把手机的开发者选项模式打开并用数据线连接电脑(废话)

2)打开eclipse切换到DDMS视图如下图

3)击选中 Devices 视图界面中最上方一排图标中的“Update Heap”图标:

接着手机进入应用要测试排查是否有泄露的activity或者fragment,之后在DDMS右边的视图点击一下Cause GC,让虚拟机强制GC一次,之后就不用点了,它会自动刷新视图(点击以后可能会卡住一段时间这属于正常的).然后观察GC后的data ovhect的 Total size和Count.尝试关闭当前页面并重新进入,反复进行如此操作后看Count和Total size在GC后会不会有明显回落接近之前GC后的值,如果多次操作GC后内存呈现较大的增加趋势那么,这个页面可能会有问题!!

或者也可以尝试使用MAT内存分析工具去分析内存泄露的原因,我功力尚浅只是浅尝即止有兴趣可以根据这篇教程去看

http://rayleeya.iteye.com/blog/1956638

3.怎样去解决OOM

我所碰到的OOM问题暂时就这三种情况

1)在一些单例的构造方法中需要传入一个context,传入了activity的context,导致单例持有这个activity的引用不能让其回收.

例如操作数据库的UserDatabase类,它是单例的主要用来打开关闭数据库存放数据,我们项目中之前写得人忽略了这一点,传入的context是acitivity的,因为单例的生命周期和整个程序的生命周期一样长,建议直接使用Application的context.

2)静态的成员变量

有时因为一些原因(比如希望节省Activity初始化时间等),将一些对象设置为static的,我们会忘了在activity退出的时候把这些变量的引用给释放,所以导致和这个变量相关的Activity强引用的其他对象也无法被释放,这样就造成了内存泄露.建议在onDestroy方法中把这些static的变量给置为null;

3)注册/取消监听对象

经常要用到一些XxxListener对象,或者是XxxObserver、XxxReceiver对象,然后用registerXxx方法注册,用unregisterXxx方法注销。本身用法也很简单,但是从一些实际开发中的代码来看,仍然会有一些问题: registerXxx和unregisterXxx方法的调用通常也和Cursor的打开/关闭类似,在Activity的生命周期中成对的出现即可:

在 onCreate() 中 register,在 onDestroy() 中 unregitster;

在 onStart() 中 register,在 onStop() 中 unregitster;

在 onResume() 中 register,在 onPause() 中 unregitster;

最近碰到的问题,在fragment中定义了一个PhoneStateListener的对象,将其注册到TelephonyManager中:

TelephonyManager.listen(l,PhoneStateListener.LISTEN_SERVICE_STATE);

但是在Activity退出的时候注销掉这个监听,即没有调用以下方法:

TelephonyManager.listen(l,PhoneStateListener.LISTEN_NONE);

因为PhoneStateListener的成员变量callback,被注册到了TelephonyRegistry中,TelephonyRegistry是后台的一个服务会一直运行着。所以如果不注销,则callback对象无法被释放,PhoneStateListener对象也就无法被释放,最终导致Activity对象无法被释放

参考资料:

http://rayleeya.iteye.com/blog/1956059

时间: 2024-10-25 19:34:25

android 内存溢出OOM问题的相关文章

【Android】Android内存溢出问题---用自行开辟的空间进行对内存管理

public static Bitmap readBitmap(String path) { BitmapFactory.Options options = new BitmapFactory.Options(); options.inPreferredConfig = Bitmap.Config.RGB_565; options.inPurgeable = true; options.inInputShareable = true; options.inSampleSize = compute

内存溢出(Oom)和内存泄露(Memory leak)

内存溢出(Oom):运行内存大于可用内存的情况.比如申请了一个integer空间,结果存放下了只有long才能存放的数据 内存泄露(Memory leak):程序员忘记释放已用内存的情况,是内存管理较为常见的现象 以发生的方式来分类,内存泄漏可以分为4类: 1. 常发性内存泄漏.发生内存泄漏的代码会被多次执行到,每次被执行的时候都会导致一块内存泄漏. 2. 偶发性内存泄漏.发生内存泄漏的代码只有在某些特定环境或操作过程下才会发生.常发性和偶发性是相对的.对于特定的环境,偶发性的也许就变成了常发性

android 内存溢出的一些想法

对于android内存溢出这个问题,小编很是头痛!在这里说下小编自己的想法! 首先内存引用分为强引用,弱引用,软引用,虚引用! 强引用是一个实例引用,根据java的gc原理,如果存在引用,就无法自动回收,所以强引用必须在用完后使其=null ex:Object object = new Object(); object = null; 软引用是在强引用的基础上引用,使用Softreference进行引用,它是除非系统内存不足时才会回收,其它时候均不会回收,适合做cache: ex: Object

Android 内存溢出管理与测试

今天发现正在做的项目,时不时的会报错:dalvikvm heap out of memory on a 7458832-byte allocation (堆分配的内存溢出) 为什么会内存溢出呢?我以前从未遇见这种情况.后来在网上查了查资料,还是挺多的. 怎么说呢?因为Android开发基本上是以java语言为基础,那么程序是在java虚拟机上运行的.而虚拟机不允许单个程序中的Bitmap占用超过8M的内存,从报错的日志可以看出:7458832-byte大约就是7M多的样子,基本吻合上述数据.在我

【转载】Android 内存溢出如何发生的。

且谈Android内存溢出 前言 关于android的内存溢出在创新文档库中也有不少,网络上也有很多这方面的资料.所以这遍文章不算是正真意义上的创新,仅仅只是对xxx源码中出现的一些android开发中容易犯错的代码习惯一次总结. 1.  Android的内存溢出是如何发生的 Android的虚拟机是基于寄存器的Dalvik,它的最大堆大小一般是16M,有的机器为24M.因此我们所能利用的内存空间是有限的.如果我们的内存占用超过了一定的水平就会出现OutOfMemory的错误. 原因主要有两个:

Android 内存溢出解决方案(OOM)

众所周知,每个Android应用程序在运行时都有一定的内存限制,限制大小一般为16MB或24MB(视平台而定).因此在开发应用时需要特别关注自身的内存使用量,而一般最耗内存量的资源,一般是图片.音频文件.视频文件等多媒体资源:由于Android系统对音频.视频等资源做了边解析便播放的处理,使用时并不会把整个文件加载到内存中,一般不会出现内存溢出(以下简称OOM)的错误,因此它们的内存消耗问题暂不在本文的讨论范围.本文重点讨论的是图片的内存消耗问题,如果你要开发的是一款图片浏览器应用,例如像And

Android 内存溢出解决方案(OOM) 整理总结

标签:Android加载大 Android 移动开发 在最近做的工程中发现加载的图片太多或图片过大时经常出现OOM问题,找网上资料也提供了很多方法,但自己感觉有点乱,特此,今天在不同型号的三款安卓手机上做了测试,因为有效果也有结果,今天小马就做个详细的总结,以供朋友们共同交流学习,也供自己以后在解决OOM问题上有所提高,提前讲下,片幅有点长,涉及的东西太多,大家耐心看,肯定有收获的,里面的很多东西小马也是学习参考网络资料使用的,先来简单讲下下: 一般我们大家在遇到内存问题的时候常用的方式网上也有

Android内存溢出解决方案(OOM)

众所周知,每个Android应用程序在运行时都有一定的内存限制,限制大小一般为16MB或24MB(视平台而定).因此在开发应用时需要特别关注自身的内存使用量,而一般最耗内存量的资源,一般是图片.音频文件.视频文件等多媒体资源:由于Android系统对音频.视频等资源做了边解析便播放的处理,使用时并不会把整个文件加载到内存中,一般不会出现内存溢出(以下简称OOM)的错误,因此它们的内存消耗问题暂不在本文的讨论范围.本文重点讨论的是图片的内存消耗问题,如果你要开发的是一款图片浏览器应用,例如像And

各路搜集,分析Android内存溢出

叙述不当之处,欢迎指正. Android主要应用在嵌入式设备当中,而嵌入式设备由于一些众所周知的条件限制,通常都不会有很高的配置,特别是内存是比较有限的.如果我们编写的代 码当中有太多的对内存使用不当的地方,难免会使得我们的设备运行缓慢,甚至是死机.为了能够使得Android应用程序安全且快速的运行,Android 的每个应用程序都会使用一个专有的Dalvik虚拟机实例来运行,它是由Zygote服务进程孵化出来的,也就是说每个应用程序都是在属于自己的进程中运行的.一方面,如果程序在运行过程中出现