Android Out Of Memory(OOM) 的详细研究

Android项目开发中如何避免内存溢出(Out of Memory) 强引用是使用最普遍的引用。如果一个对象具有强引用,那垃圾回收器绝不会回收它。 当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足的问题。 阅读详情

  基于Android开发多媒体和游戏应用时,可能会挺经常出现Out Of Memory 异常 ,顾名思义这个异常是说你的内存不够用或者耗尽了。
        在Android中,一个Process 只能使用16M内存,如果超过了这个限制就会跳出这个异常。这样就要求我们要时刻想着释放资源。Java的回收工作是交给GC的,如何让GC能及时的回收已经不是用的对象,这个里面有很多技巧,大家可以google一下。
        因为总内存的使用超过16M而导致OOM的情况,非常简单,我就不继续展开说。值得注意的是Bitmap在不用时,一定要recycle,不然OOM是非常容易出现的。
         本文想跟大家一起讨论的是另一种情况:明明还有很多内存,但是发生OOM了。
        这种情况经常出现在生成Bitmap的时候。有兴趣的可以试一下,在一个函数里生成一个13m 的int数组。
        再该函数结束后,按理说这个int数组应该已经被释放了,或者说可以释放,这个13M的空间应该可以空出来,
        这个时候如果你继续生成一个10M的int数组是没有问题的,反而生成一个4M的Bitmap就会跳出OOM。这个就奇怪了,为什么10M的int够空间,反而4M的Bitmap不够呢?
       这个问题困扰很久,在网上,国外各大论坛搜索了很久,一般关于OOM的解释和解决方法都是,如何让GC尽快回收的代码风格之类,并没有实际的支出上述情况的根源。
       直到昨天在一个老外的blog上终于看到了这方面的解释,我理解后归纳如下:
         在Android中:
       1.一个进程的内存可以由2个部分组成:java 使用内存 ,C 使用内存 ,这两个内存的和必须小于16M,不然就会出现大家熟悉的OOM,这个就是第一种OOM的情况。
       2.更加奇怪的是这个:一旦内存分配给Java后,以后这块内存即使释放后,也只能给Java的使用,这个估计跟java虚拟机里把内存分成好几块进行缓存的原因有关,反正C就别想用到这块的内存了,所以如果Java突然占用了一个大块内存,即使很快释放了:
        C能使用的内存 = 16M - Java某一瞬间占用的最大内存。
       而Bitmap的生成是通过malloc进行内存分配的,占用的是C的内存,这个也就说明了,上述的4MBitmap无法生成的原因,因为在13M被Java用过后,剩下C能用的只有3M了。
 
下面是我参考的blog的所有内容:
内如如下:

> You might try to pre-allocate bitmap memory before launching the WebViews?It's not the WebView that's triggering the OOM, but some arbitrary otherpiece of code that needs memory that is not *there* anymore. Very often thisis happening when starting a new activity.

Ok, I see, I have to start dealing with automating my apology. 

There is one more, small thing that I can do. I also do some downloading andXML parsing in the background at times. This only takes Java Heap (<3MB),but maybe I should move that stuff to a separate process. This may lower thechances of an OOM. I'll think about it, but with all the added complexity ofinter process communication I am not sure I would want to go there.

Anyway, thanks for sharing your insights. That was very helpful.

 On Wed, Oct 7, 2009 at 10:48 PM, Tom Gibara <[EMAIL PROTECTED]> wrote: 
> I think it's better to add a couple more columns to the table to see the 
> picture (as I see it) more clearly:> JH = Java Heap
> JU = Memory actually used by Java
> NH = Native Heap 
> TU = Total memory Used = JU + NH
> TA = Total memory Allocated = JH + NH 
>
> (note I'm not distinguishing between native heap and native heap used 
> because it's not relevant here)
>
> The system requires TA (the process size as you called it) to not exceed 
> 16MB, the evolution is:
> 
> JU JH NH TU TA 
> 1) 2 2 0 2 2
> 2) 4 4 0 4 4
> 3) 4 4 2 6 6 
> 4) 14 14 2 16 16
> 5) 4 14 2 6 16 
> 6) 4 14 4 10 18 *** OH NO! *** 
>
> The key is what happens between (4) and (5): GC reclaims 10MB (JU reduced> by 10MB) but the java heap doesn't shrink (JH stays at 14MB). This enlarged > java heap basically squeezes the maximum native heap allocation.
> 
> The simplest approach is to try and ensure that your application maintains 
> a 'flatish' memory profile - no big spikes. You should do this anyway, since 
> it means that your application is being well behaved and won't force other 
> apps to be terminated just because your application needs a temporary shot> of memory (which will then remain as a glut until the application restarts).
>
> As you point out, WebViews are heavy on memory usage, and these might be 
> what's causing your memory usage to spike. I don't have any good suggestions 
> for a fix. You might try to pre-allocate bitmap memory before launching the 
> WebViews? It might work, but it may be complicated to do and could cause 
> OOMs when WebViews are instantiated - no way around that, your application
> is simply using too much memory at that point. 
>

2012年02月04日  更新:

16M是怎么来的?算是实验来的吧,每个机型不一样,模拟器不同版本也不一样,可以通过:
Runtime.getMaxMemory() 来查看。

long maxMemory()
Returns the maximum amount of memory that may be used by

Android内存泄漏:检测关键函数并解决GL_OUT_OF_MEMORY和GL error: Out of memory! OpenGLRenderer We 通过使用适当的内存分析工具,仔细检查关键函数的实现,并正确处理上下文引用,我们可以有效地检测和解决与GL_OUT_OF_MEMORY和GL error: Out of memory!通过在应用程序的入口点(例如Application类的onCreate方法)中安装LeakCanary,我们可以在应用程序运行时监测内存泄漏,并在发现内存泄漏时提供详细的报告和堆栈跟踪信息。对象引用未正确释放:当一个对象的引用仍然存在,但应该被销毁时,该对象将无法被垃圾回收器回收,从而导致内存泄漏。函数释放了纹理对象。 阅读详情

相关推荐

Android避免内存溢出(Out of Memory)方法汇总

主要为大家详细介绍了Android避免内存溢出Out of Memory方法汇总,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

Android 解决OutOfMemory,从避免内存溢出开始

前言:一个刚上班和三年工作经验的安卓程序猿,做同一个项目。如果只从表面上看,并没有什么区别。但从项目的性能、稳定性、扩展性等方面来观察的话,差别不要太大。言归正传,今天我们来说一下安卓开发中很常见的问题,内存溢出 out of memory。一、什么是内存溢出和内存泄漏。内存溢出:内存溢出有两种情况,一种是指你申请了10个字节的空间,但是你在这个空间写入11或以上字节的数据,就是溢出。还有一种是内存

qq_35372900的博客 5595

AI变现案例实战系列4:AI数字员工团队——用OpenClaw搭建6个智能体,自动运营你的赚钱系统

摘要:谷歌AI产品经理Shubham Saboo利用OpenClaw搭建6人AI团队,实现内容创作、技术开发等任务自动化,每月成本不足400美元。文章对比阿里云和Windows本地两种部署方案,提供详细配置指南。通过多Agent架构实现物理隔离与精准协作,可创建6个专业AI角色(如研究员、运营、工程师等),每个Agent专注单一任务,避免记忆负担和上下文污染问题。阿里云方案适合长期稳定运行,Windows本地部署则适合零成本测试。最终可组建高效AI团队,实现7x24小时无人值守运营。(149字)

小明的博客 1141

【转】Android Out Of Memory(OOM)的详细研究

Android Out Of Memory(OOM) 的詳細研究 基於Android開發應用時,可能會挺時常出現Out Of Memory 異常.在Android中,一個Process 只能使用16M記憶體,要是超過了這個限定就會跳出這個異常。這樣就要求我們要時刻想著開釋資源。Java的回收工作是交給GC的,如何讓GC能即時的回收已經不是用的物件,這個裏面有許多技巧,各人可以google

taki_dsm的专栏 1577

【mysql8.0.33安装详情教程】

8、进入Account and Roles界面,输入密码,再点击next(密码随便输,自己记住就行)11、进入Apply Configuration界面,直接点Execute,等待应用成功。14、输入密码,点击check,检查是否正确。3、下图是选择安装类型,选择默认安装就可以,然后点击“next”。5、进入Product Configuration,点击next。9、进入Windows Service界面,直接点击next。15、点击Execute执行安装(完成后点击Finish)二、验证是否安装成功。

98渣渣辉的博客 2114

Linux V4L2驱动开发实战:手把手教你用I2C摄像头Sensor注册一个v4l2_subdev

本文详细解析了Linux V4L2驱动开发中I2C摄像头Sensor注册v4l2_subdev的全流程,包括初始化、操作集填充、异步匹配等关键环节。通过实战案例和代码示例,帮助开发者掌握V4L2子系统下的摄像头驱动开发技巧,提升嵌入式Linux系统开发能力。

weixin_30328063的博客 420

Android Out Of Memory(OOM) 的詳細研究

Android Out Of Memory(OOM) 的詳細研究 http://blog.sina.com.cn/s/blog_487190650100st2t.html 基於Android開發應用時,可能會挺時常出現Out Of Memory 異常.在Android中,一個Process 只能使用16M記憶體,要是超過了這個限定就會跳出這個異常。這樣就要求我們要時

火星人在地球的专栏 626

Rocky Linux 9.0国内yum源一键替换指南(上海交大镜像站实测)

本文详细介绍了如何将Rocky Linux 9.0的yum源替换为上海交大镜像站,以解决国内用户访问官方源速度慢的问题。通过实测验证,上海交大镜像站提供高速下载和稳定更新,并提供了完整的替换步骤、常见问题解决方案及高级优化配置,帮助用户提升软件包下载效率。

weixin_29304985的博客 362

转载:Android Out Of Memory(OOM) 的详细研究

基于Android开发多媒体和游戏应用时,可能会挺经常出现Out Of Memory 异常 ,顾名思义这个异常是说你的内存不够用或者耗尽了。 在Android中,一个Process 只能使用16M内存,如果超过了这个限制就会跳出这个异常。这样就要求我们要时刻想着释放资源。Java的回收工作是交给GC的,如何让GC能及时的回收已经不是用的对象,这个里面有很多技巧,大家可以google一下。 因为

快慢机的地盘 1032

差分运放实战:如何快速计算带直流偏置的电路(附详细推导步骤)

本文详细解析了差分运放电路在带直流偏置设计中的核心计算方法和实战技巧。通过可视化参数关系和分步拆解,帮助工程师快速掌握电路设计精髓,包括虚短虚断原理、偏置电压计算及非理想因素处理,提升信号调理和传感器接口设计的效率与精度。

o4p5q6r7s的博客 412

基于Cesium的简易淹没分析效果

淹没分析是通过模拟水体扩散过程来评估洪水、海平面上升等情景下可能影响的区域,其核心作用是为防灾减灾、规划设计和风险管理提供科学依据。预测淹没的范围、水深和持续时间,识别高风险区域,帮助政府制定应急预案和疏散路线,减少人员伤亡和财产损失。

星云数海的博客,一个专注GIS十多年的GISer人。 531
上一篇: Android进程的内存管理分析
下一篇: Android内存泄漏分析及调试
cding1818
博客等级 码龄17年 963粉丝 154原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值