(三)如何避免OOM总结

前面介绍了一些基础的内存管理机制以及OOM的基础知识,那么在实践操作当中,有哪些指导性的规则可以参考呢?归纳下来,可以从四个方面着手,首先是减小对象的内存占用,其次是内存对象的重复利用,然后是避免对象的内存泄露,最后是内存使用策略优化。

减小对象的内存占用

避免OOM的第一步就是要尽量减少新分配出来的对象占用内存的大小,尽量使用更加轻量的对象。

1)使用更加轻量的数据结构

例如,我们可以考虑使用ArrayMap/SparseArray而不是HashMap等传统数据结构。图8演示了HashMap的简要工作原理,相比起Android专门为移动操作系统编写的ArrayMap容器,在大多数情况下,都显示效率低下,更占内存。通常的HashMap的实现方式更加消耗内存,因为它需要一个额外的实例对象来记录Mapping操作。另外,SparseArray更加高效,在于他们避免了对key与value的自动装箱(autoboxing),并且避免了装箱后的解箱。

 

图8  HashMap简要工作原理

关于更多ArrayMap/SparseArray的讨论,请参考《 Android性能优化典范(三)》的前三个段落。

2)避免在Android里面使用Enum

Android官方培训课程提到过“Enums often require more than twice as much memory as static constants. You should strictly avoid using enums on Android.”,具体原理请参考《Android性能优化典范(三)》,所以请避免在Android里面使用到枚举。

3)减小Bitmap对象的内存占用

Bitmap是一个极容易消耗内存的大胖子,减小创建出来的Bitmap的内存占用可谓是重中之重,通常来说有以下2个措施:

 

  • inSampleSize:缩放比例,在把图片载入内存之前,我们需要先计算出一个合适的缩放比例,避免不必要的大图载入。
  • decode format:解码格式,选择ARGB_8888/RBG_565/ARGB_4444/ALPHA_8,存在很大差异。

 

4)使用更小的图片

在涉及给到资源图片时,我们需要特别留意这张图片是否存在可以压缩的空间,是否可以使用更小的图片。尽量使用更小的图片不仅可以减少内存的使用,还能避免出现大量的InflationException。假设有一张很大的图片被XML文件直接引用,很有可能在初始化视图时会因为内存不足而发生InflationException,这个问题的根本原因其实是发生了OOM。

内存对象的重复利用

大多数对象的复用,最终实施的方案都是利用对象池技术,要么是在编写代码时显式地在程序里创建对象池,然后处理好复用的实现逻辑。要么就是利用系统框架既有的某些复用特性,减少对象的重复创建,从而降低内存的分配与回收(如图9所示)。

 

图9  对象池技术

在Android上面最常用的一个缓存算法是LRU(Least Recently Use),简要操作原理如图10所示。

 

图10  LRU简要操作原理

1)复用系统自带的资源

Android系统本身内置了很多的资源,比如字符串、颜色、图片、动画、样式以及简单布局等,这些资源都可以在应用程序中直接引用。这样做不仅能减少应用程序的自身负重,减小APK的大小,还可以在一定程度上减少内存的开销,复用性更好。但是也有必要留意Android系统的版本差异性,对那些不同系统版本上表现存在很大差异、不符合需求的情况,还是需要应用程序自身内置进去。

2)注意在ListView/GridView等出现大量重复子组件的视图里对ConvertView的复用,如图11所示。

 

图11

3)Bitmap对象的复用

在ListView与GridView等显示大量图片的控件里,需要使用LRU的机制来缓存处理好的Bitmap,如图12所示。

 

图12

 

  • 利用inBitmap的高级特性提高Android系统在Bitmap分配与释放执行效率(注:3.0以及4.4以后存在一些使用限制上的差异)。使用inBitmap属性可以告知Bitmap解码器去尝试使用已经存在的内存区域,新解码的Bitmap会尝试去使用之前那张Bitmap在Heap中所占据的pixel data内存区域,而不是去问内存重新申请一块区域来存放Bitmap。利用这种特性,即使是上千张的图片,也只会仅仅只需要占用屏幕所能够显示的图片数量的内存大小,如图13所示。

 

 

图13  利用inBitmap的高级特性提高Android在Bitmap分配与释放执行效率

使用inBitmap需要注意几个限制条件:

 

  • 在SDK 11 -> 18之间,重用的Bitmap大小必须是一致的。例如给inBitmap赋值的图片大小为100-100,那么新申请的Bitmap必须也为100-100才能够被重用。从SDK 19开始,新申请的Bitmap大小必须小于或者等于已经赋值过的Bitmap大小。
  • 新申请的Bitmap与旧的Bitmap必须有相同的解码格式。例如大家都是8888的,如果前面的Bitmap是8888,那么就不能支持4444与565格式的Bitmap了。我们可以创建一个包含多种典型可重用Bitmap的对象池,这样后续的Bitmap创建都能够找到合适的“模板”去进行重用,如图14所示。

 

 

图14

另外,在2.x的系统上,尽管Bitmap是分配在Native层,但还是无法避免被计算到OOM的引用计数器里。这里提示一下,不少应用会通过反射vBitmapFactory.Options里面的inNativeAlloc来达到扩大使用内存的目的,但是如果大家都这么做,对系统整体会造成一定的负面影响,建议谨慎采纳。

4)避免在onDraw方法里面执行对象的创建

类似onDraw等频繁调用的方法,一定需要注意避免在这里做创建对象的操作,因为他会迅速增加内存的使用,而且很容易引起频繁的gc,甚至是内存抖动。

5)StringBuilder

在有些时候,代码中会需要使用到大量的字符串拼接的操作,这种时候有必要考虑使用StringBuilder来替代频繁的“+”。

内容来源于 小红提技术博客,http://www.xiaohongti.com/ 转载请保留地址,尊重版权。

Netty | 设置高低水位线避免 OOM Netty 中的高低水位线是什么? Netty 中的 Channel 都有一个写缓冲区; 这个写缓冲区是 ChannelOutboundBuffer,这是个 Netty 发数据时的仓库,要发送的数据以数据结构 Entry 的形式存在仓库中,Entry 是个链表中的节点; Netty 中的高低水位线,对应的就是这个链表中节点的数量范围,用于限制程序的写操作,自己在写程序的时候,需要... 阅读详情

相关推荐

Android 多种方式正确的加载图像,有效避免oom

图像加载的方式:        Android开发中消耗内存较多一般都是在图像上面,本文就主要介绍怎样正确的展现图像减少对内存的开销,有效的避免oom现象。 首先我们知道我的获取图像的来源一般有三种源头: 1.从网络加载 2.从文件读取 3.从资源文件加载        针对这三种情况我们一般使用BitmapFactory的:decodeStream, decodeFile,decod

thinkCoolys的专栏 5259

java异常_Java程序员必备:常见OOM异常分析(原因+排查解决思路+demo代码+运行结果)...

整理了JVM发生OOM异常的几种情况,并分析原因以及解决方案,希望对大家有帮助。Java 堆溢出Java堆用于存储对象实例,只要不断地创建对象,并且保证GC Roots到对象之间有可达路径来避免垃圾回收机制清除这些对象,那么在对象数量到达最大堆的容量限制后就会产生内存溢出异常。Java 堆溢出原因无法在 Java 堆中分配对象应用程序保存了无法被GC回收的对象。应用程序过度使用 finalize...

weixin_39600447的博客 477

EasyExcel 导出上万数据如何避免OOM

Excel 导出功能:大数据量的情况下,很容易出现 OOM。数据量不大没有什么问题,做法是直接查全量数据,然后直接往Excel里写。但是当数据量逐渐多了起来后,达到一万多条,导出的时候就会报OOM。然后换成了阿里开源的EasyExcel,但是导出的时候也不太稳定,偶尔也会出现OOM。所以应该是数据量太大了,在写入的时候把内存占满了。解决方式:放弃了查全量数据一次性写入Excel的做法,采用分页查询,分批次写入Excel的方式,果然不会出现OOM了。

人生苦短,及时行乐 3591

分析几种预防OOM的方法

一、OOM介绍 1、VM运行时内存分析 JVM执行Java程序的过程中,会使用到各种数据区域,这些区域有各自的用途、创建和销毁时间。JVM包括下列几个运行时数据区域: 1.程序计数器(Program Counter Register): 此内存区域是唯一一个在VM Spec中没有规定任何OutOfMemoryError情况的区域。 2.Java虚拟机栈(Java Virtual Machi...

whh的博客 1904

Java内存管理:避免OOM的10个使用小技巧

监控和分析内存使用使用JVM提供的工具(如jvisualvm, jconsole)监控和分析应用的内存使用情况,及时发现并解决内存问题。10、优化GC策略根据应用的实际情况,调整和优化GC策略,减少GC的执行时间,提升系统的性能。避免OOM错误并非难事,关键在于对Java内存管理有深入的理解和正确的实践。通过以上10个实用小技巧的应用,可以有效地管理和优化Java应用的内存使用,避免内存溢出的问题。务必记得,持续的监控、分析和优化是保持应用稳定运行的关键。

程序员江小北 2103

K8S OOM killer机制

当kubelet没来得及触发pod驱逐,使得节点内存耗尽时,将触发节点上的OOM killer机制;Linux上有个机制叫OOM killer(Out Of Memory killer),这个机制会在系统内存耗尽的情况下发挥作用,即根据一定的算法规则,选择性的杀死一些进程,以释放部分内存,让系统继续稳定运行。

sre救赎之路 1738

linux OOM 惹的祸

Linux 在内存不足的时候不至于出太严重的问题,把无关紧要的进程杀掉; LINUX 2.6 上是杀掉占用内存最厉害的进程; OOM Killer 的关闭与激活方式: # echo "0" > /proc/sys/vm/oom-kill # echo "1" > /proc/sys/vm/oom-kill 通过调整进程相应目录下的/proc/[PID]/oom_adj来实现的,其中oo

chenmeng4735的专栏 557

【论文翻译】Enhancing Channel Estimation in High Mobility OTFS Systems: A Novel Pilot-Based Method...

本文介绍了一种用于正交时频空间(OTFS)调制系统的新型基于导频的信道估计方法。我们提出的方法是在ZP-OTFS系统的零填充区域插入一行导频符号,具有减少开销和降低峰均功率比(PAPR)的显著优势。特别是,通过沿多普勒轴分布导频符号,我们的方法在高移动性场景下依然能够提供鲁棒且精确的信道估计,这是像TransPod这种时速超过1000 km/h的运输系统的一个典型特征。这一点至关重要,因为在此类场景下,多普勒频移可能会导致系统性能的严重退化。

Cuby的博客 1214

内存优化

Random Access Memory(RAM)在任何软件开发环境中都是一个很宝贵的资源。 尽管 Android 的 Dalvik 虚拟机扮演了常规的垃圾回收角色,但并不意味着可以忽视 App 的内存分配与释放的时机与地点。这里总结一些内存管理的知识,以及在开发 Android 应用时如何主动减少内存的使用。

野人的小本本 390

从Chiplet到UCIE:D2D互联技术如何重塑半导体设计生态

本文探讨了D2D互联技术在半导体设计中的革命性作用,从Chiplet到UCIE标准的演进如何重塑行业生态。详细分析了D2D互联的技术本质、架构选择及UCIE标准带来的变革,并展望了未来光学D2D和3D集成等趋势。高速互联接口技术的突破为AI加速器和计算芯片提供了更高带宽和能效。

weixin_29292535的博客 932

微处理器实验报告-实验四

实验四 可编程定时/计数器8253实验 一、实验要求 利用8086外接8253可编程定时/计数器,可以实现方波的产生。 二、实验目的 1、学习8086与8253的连接方法。 2、学习8253的控制方法。 3、掌握8253定时器/计数器的工作方式和编程原理

青竹小轩的博客 5113

YOLO11如何避免OOM?显存优化三步法详解

本文介绍了基于星图GPU平台自动化部署YOLO11镜像的实践方法,结合显存优化三步法有效避免训练中的OOM问题。该平台支持开箱即用的YOLO11环境,适用于模型微调、目标检测等AI应用开发场景,助力开发者在有限硬件资源下高效完成深度学习任务。

weixin_35920379的博客 456

5分钟搞定Vivado IP核的VCS仿真:从Export脚本到Verdi波形查看全流程

本文详细介绍了如何利用Vivado的Export Simulation功能,快速搭建Vivado IP核的VCS与Verdi联合仿真环境。通过自动化脚本生成、FSDB波形配置及高效调试技巧,实现从工程导出到波形查看的全流程,大幅提升FPGA验证效率,尤其适合IC验证工程师和竞赛团队。

weixin_29306261的博客 482

Android 面试题 避免OOM(内存优化)三

Android和java中都会出现由于不良代码引起的内存泄露,为了使Android应用程序能够快速高效的运行,Android每个应用程序都会有专门Dalvik虚拟机实例来运行,也就是每个程序都在属于自己的进程中运行。某个应用程序内存泄露仅仅只会使自己进程被kill掉不会影响其他进程(如果是system_process等系统进程出现问题,就会造成系统重启),另一方面,系统为每一个应用程序分配了不同的内存上限,如果超过这个上限被视为内存泄露,从而被kill掉。

我很好 833

CANoe中如何仿真报文的CRC和Counter,告诉你三种方法皆可实现

CANoe中如何仿真报文的CRC和Counter

蚂蚁小兵 5284

2025年12月GESP真题及题解(C++一级): 小杨的爱心快递

2025年12月GESP真题及题解(C++一级): 小杨的爱心快递

王老师青少年编程 1652

OOM内存优化建议

都会创建新的 numpy 数组副本(

E8rrr的博客 194

【我的Android进阶之旅】异常: Problems reading data from Binary store in Local\Temp\gradlexxx.bin (exist: true)

一、异常描述 今天开个会议,电脑自动关机了,重启电脑之后,打开Android Studio,编译代码,就编译失败,如下所示:异常提示 : Caused by: java.lang.RuntimeException: Problems reading data from Binary store in C:\Users\000\AppData\Local\Temp\gradle6337489649031706149.bin (exist: true) Caused by: java.lang.Runtime

字节卷动 3825

OOM的产生以及如何避免

一、什么是OOM OOM(out of memory)即内存泄露。一个程序中,已经不需要使用某个对象,但是因为仍然有引用指向它垃圾回收器就无法回收它,当该对象占用的内存无法被回收时,就容易造成内存泄露。 Android的一个应用程序的内存泄露对别的应用程序影响不大,因为为了能够使得Android应用程序安全且快速的运行,Android的每个应用程序都会使用一个专有的Dalvik虚拟机实例来运行

YvonneVon的博客 1770

ardupilot开发 --- Remote ID 篇

适配ardupilot的Remote ID模块研发,远程标识模块研发。Remote ID模块可以通过蓝牙或wifi向外广播无人机的状态信息、位置信息、任务信息等,并可以通过蜂窝数据向国家无人驾驶航空器一体化综合监管服务平台上报这些信息。Remote ID功能是21年起国家出台的民用无人机适航飞行的基本要求!

记录老板的每次pua,分享领导每天的毒鸡汤... 9608

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

如何理解和避免OOM

理解和避免 OutOfMemoryError 需要综合考虑多个方面,包括内存泄漏检测和修复、优化大对象分配、处理内存碎片化和资源管理等。通过采用一些最佳实践和使用合适的工具,可以有效地降低 OOM 的风险,提高应用程序的稳定性和性能。在开发过程中,要时刻关注内存使用情况,并进行及时的优化和调整,以确保应用程序在各种情况下都能正常运行。

challenge51all的专栏 915

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

如何避免OOM异常

如何避免OOM异常 OOM 内存溢出,想要避免 OOM 异常首先我们要知道什么情况下会导致OOM异常。 1、图片过大导致OOM Android 中 用 bitmap 时 很 容 易 内 存 溢 出 , 比 如 报 如 下 错 误 : Java.lang.OutOfMemoryError : bitmap size exceeds VM budget。 解决方法: 方法1: 等比例缩

Run__Forever的博客 1314

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

Android如何避免OOM总结

前面介绍了一些基础的内存管理机制以及OOM的基础知识,那么在实践操作当中,有哪些指导性的规则可以参考呢?归纳下来,可以从四个方面着手,首先是减小对象的内存占用,其次是内存对象的重复利用,然后是避免对象的内存泄露,最后是内存使用策略优化。 1)使用更加轻量的数据结构 例如,我们可以考虑使用ArrayMap/SparseArray而不是HashMap等传统数据结构,下图演示了HashMap的简要工...

fanleiym的专栏 449

Android 如何避免OOM

Android 如何避免OOM

caialun的专栏 865

如何避免OOM总结

如何避免OOM总结 前面介绍了一些基础的内存管理机制以及OOM的基础知识,那么在实践操作当中,有哪些指导性的规则可以参考呢?归纳下来,可以从四个方面着手,首先是减小对象的内存占用,其次是内存对象的重复利用,然后是避免对象的内存泄露,最后是内存使用策略优化。 减小对象的内存占用 避免OOM的第一步就是要尽量减少新分配出来的对象占用内存的大小,尽量使用更加轻量的对象。 1)使用

纸上得来终觉浅,绝知此事要躬行 2754
上一篇: (二)OOM(Out Of Memory)
下一篇: (四)避免对象的内存泄露
yufei_java
博客等级 码龄10年 18粉丝 60原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值