ANDROID BITMAP内存限制OOM,OUT OF MEMORY

合集下载

oom解决方案

oom解决方案

oom解决方案《解决OOM问题的有效方法》OOM(Out of Memory)是指程序在执行过程中耗尽了所有可用的内存资源,导致系统无法继续正常运行的问题。

在大型软件开发中,OOM问题是一个常见且具有挑战性的难题,需要开发人员采取有效的解决方法来应对。

针对OOM问题,下面提供一些有效的解决方案:1. 内存泄漏排查:首先要排查程序中是否存在内存泄漏的情况。

内存泄漏是指程序分配了内存空间,但在不再需要的情况下没有释放该内存空间,导致内存资源被长时间占用而无法释放。

通过内存泄漏排查工具,可以帮助开发人员找出内存泄漏的位置,并进行相应的修复。

2. 增加内存资源:如果程序的内存需求超过了系统当前可用的内存资源,可以考虑增加系统的内存资源。

通过升级硬件或者优化系统内存配置,可以增加程序可用的内存空间,从而缓解OOM问题。

3. 优化程序性能:对程序进行性能优化是解决OOM问题的重要手段。

通过减少内存占用、优化算法等方式,可以降低程序的内存需求,从而减少出现OOM的可能性。

4. 使用内存管理工具:借助内存管理工具,可以对程序的内存使用情况进行监控和管理。

通过实时监控内存使用情况,并对内存使用进行优化,可以有效地避免OOM问题的发生。

5. 分析堆转储文件:当程序发生OOM时,可以通过生成堆转储文件进行分析。

堆转储文件可以帮助开发人员了解程序在OOM发生时的内存状态,从而更好地定位和解决OOM问题。

总之,解决OOM问题需要综合考虑程序本身的内存使用情况、系统资源配置以及程序性能优化等方面的因素。

只有通过有效的手段和方法,才能更好地应对和解决OOM问题,确保程序能够稳定可靠地运行。

bitmap释放流程

bitmap释放流程

bitmap释放流程Bitmap释放流程介绍Bitmap是Android开发中经常用到的一种图片格式,但是如果不正确地释放Bitmap,会导致内存泄漏和OOM(Out of Memory)问题。

本文将详细说明Bitmap的释放流程,以帮助开发者正确处理Bitmap对象。

Bitmap内存管理1.Bitmap对象占用的内存是非常重要的资源,需谨慎管理。

2.Android提供了一种垃圾回收机制,但它对Bitmap的回收并不是即时的。

Bitmap释放流程1. 创建Bitmap•使用BitmapFactory类的decodeResource()或decodeStream()方法,根据资源文件或文件流创建Bitmap对象。

2. 使用Bitmap•在使用Bitmap对象之前,首先要确保它不为空。

3. 回收Bitmap•当Bitmap不再使用时,需要手动回收,避免造成内存泄漏。

•调用Bitmap类的recycle()方法释放Bitmap占用的内存。

•释放后的Bitmap对象将变为无效状态,不能再被使用。

4. 内存释放策略•在Activity或Fragment的生命周期方法中释放Bitmap,例如onDestroy()或onDetach()方法。

•在列表或滑动控件的回收方法中释放Bitmap,例如onViewRecycled()方法。

5. 避免Bitmap内存泄漏•不要将Bitmap对象存储在静态成员变量中。

•不要在循环中创建大量的Bitmap对象而不释放。

6. 控制Bitmap大小•根据需求,可以通过调用BitmapFactory类的Options参数的inSampleSize字段,控制Bitmap的大小。

•通过减小Bitmap的尺寸,可以减少占用的内存空间。

7. 检测内存泄漏•使用内存分析工具,例如Android Studio的内存监视器,检测内存泄漏情况。

•检查是否有未释放的Bitmap对象。

总结正确地释放Bitmap对象对于Android开发非常重要,可以有效地避免内存泄漏和OOM问题。

Android系统优化OOM问题分析

Android系统优化OOM问题分析
将在工具篇详细介绍。
发生OOM如何定位
• 内存分析工具MAT。
将在工具篇详细介绍。
如何解决OOM问题
• 创建对象时,谨慎对待其生命周期,尤其是静态对象。对象
的生命周期应与其上下文周期一致;
场景1:全局静态对象若需要调用context对象,应取Application Context,而不 应使用Activity context,以避免Activity对象无法被回收
OOM产生原因
关于GC(Android 2.3之后的版本):
• • Cocurrent,GC线程与其他线程是并发执行; Partial collection,一次可能只回收一部分垃圾;


一次垃圾回收造成的程序中止时间通常小于5s;
几种GC类型:
GC_CONCURRENT GC_FOR_MALLOC GC_EXTERNAL_ALLOC GC_HPROF_DUMP_HEAP GC_EXPLICIT
• 分析Logcat日志中dump的memory信息; • Memory相关术语: ( VSS >= RSS >= PSS >= USS )
VSS (Virtual Set Size) RSS (Resident Set Size)
进程能访问的所有内存空间大小,包含了一些没有驻留在 RAM的内存,比如mallocs已分配但尚未写入 实际占用的内存,包含所有该进程使用的共享库所占用的 内存总大小 比如3个进程共享一个库,则每个进程会计算该库占用的 1/3内存大小。很重要的参考量,系统所有进程的PSS总和 即为系统占用内存的总和。
上限,超过这个上限就会出现OOM问题。
OOM产生原因
Dalvik内存相关知识: • • Dalvik内存大体上分为Java Object Heap、Bitmap Memory和Native Heap三 种; Java Object Heap的大小,从dalvik.vm.heapstartsize读取缺省最小值,从 dalvik.vm.heapsize读取缺省最大值,这个最大值就是Android应用进程能够 使用的最大内存,超过了这个值就会造成OOM; • 在HoneyComb之后的版本,Bitmap Memory直接在Java Object Heap中分 配,可以受GC的管理。之前的版本是在Native Heap中分配的,但是大小是 计入Java Object Heap的使用大小之内的; • Native Heap是Native code(c/c++)使用的内存,不受Java Object Heap的大 小限制。

Android避免内存溢出(OutofMemory)方法总结

Android避免内存溢出(OutofMemory)方法总结

of Memory)方法总Android避免内存溢出(Out结避免内存溢出的方法,主要是对以下三个方面对程序进行优化武汉Android培训内存引用在处理内存引用之前,我们先来复习下什么是强引用、软引用、弱引用、虚引用强引用:强引用是使用最普遍的引用。

如果一个对象具有强引用,那垃圾回收器绝不会回收它。

当内存空间不足,Java 虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足的问题。

软引用:如果一个对象只具有软引用,但内存空间足够时,垃圾回收器就不会回收它;直到虚拟机报告内存不够时才会回收,只要垃圾回收器没有回收它,该对象就可以被程序使用。

软引用可用来实现内存敏感的高速缓存。

软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被垃圾回收器回收,Java虚拟机就会把这个软引用加入到与之关联的引用队列中。

弱引用:只具有弱引用的对象拥有更短暂的生命周期。

在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间是否足够,都会回收它的内存。

不过,由于垃圾回收器是一个优先级很低的线程,因此不一定会很快发现那些只具有弱引用的对象。

弱引用可以和一个引用队列(ReferenceQueue)联合使用,如果弱引用所引用的对象被垃圾回收,Java虚拟机就会把这个弱引用加入到与之关联的引用队列中。

虚引用:虚引用可以理解为虚设的引用,与其他几种引用都不同,虚引用并不会决定对象的生命周期。

如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收。

虚引用主要用来跟踪对象被垃圾回收器回收的活动。

虚引用与软引用和弱引用的一个区别在于:虚引用必须和引用队列(ReferenceQueue)联合使用。

当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之关联的引用队列中。

Android内存溢出及内存泄漏原因进解析

Android内存溢出及内存泄漏原因进解析

Android内存溢出及内存泄漏原因进解析内存溢出(Out Of Memory):Android系统中每⼀个应⽤程序可以向系统申请⼀定的内存,当申请的内存不够⽤的时候,就产⽣了内存溢出。

内存泄漏:当某个对象不再被使⽤,即不再有变量引⽤它时,该对象占⽤的内存就会被系统回收。

当某个对象不再被使⽤,但是在其他对象中仍然有变量引⽤它时,该对象占⽤的内存就⽆法被系统回收,从⽽导致了内存泄漏。

当内存泄漏过多时,可⽤内存空间会减少,应⽤程序申请的内存不够⽤,就会导致内存溢出。

内存溢出原因:1.内存泄漏过多。

2.内存中加载的数据量超过内存的可⽤量。

3.集合类(⽤于存储对象的引⽤)中有对对象的引⽤,使⽤完后未清空。

4.申请的内存不够。

5.死循环或者循环产⽣过多对象实例,导致⼤量内存被消耗。

内存泄漏原因:1.资源对象没有关闭:(1)注册⼴播接收器后没有调⽤unregisterReceiver()⽅法注销⼴播接收器。

(2)打开⽂件流之后没有调⽤close()⽅法关闭⽂件流。

(3)数据库游标cursor使⽤完后没有调⽤close()⽅法关闭游标。

(4)图⽚资源Bitmap使⽤完之后没有调⽤recycle()⽅法回收。

2.⽣命周期长的对象持有⽣命周期短的对象的引⽤,导致⽣命周期短的对象内存⽆法被回收:(1)单例模式或者静态成员变量的⽣命周期和应⽤程序的⽣命周期相等,当需要引⽤Context时,如果传⼊的是Activity的Context,Activity需要被销毁时就⽆法被回收。

解决⽅法是传⼊Application的Context,因为Application的Context⽣命周期等于应⽤程序的⽣命周期。

(2)⾮静态内部类(匿名内部类、Handler等)默认持有外部类的引⽤,如果⾮静态内部类的对象实例⽣命周期⽐外部类⽣命周期长(⽐如⾮静态内部类定义了⼀个静态的对象实例),外部类注销时就⽆法被系统回收,从⽽导致内存泄漏。

解决⽅法是采⽤静态内部类+弱引⽤的⽅式。

android 优化Bitmap

android 优化Bitmap

Android 优化Bitmap避免OutOfMemoryError使用android提供的BitmapFactory解码图片时,往往会因为图片过大而遇到OutOfMemoryError的异常。

要想正常使用,一种简便的方式是分配更少的内存空间来存储,即在载入图片的时候以牺牲图片质量为代价,将图片进行放缩,这是一种避免OOM所采用的解决方法。

但是,这种方法是得不偿失的,牺牲了图片质量。

在BitmapFactory中有一个内部类BitmapFactory.Options,其中值得我们注意的是inSampleSize和inJustDecodeBounds两个属性:inSampleSize是以2的指数的倒数被进行放缩If set to a value > 1, requests the decoder to subsample the original image, returning a smaller image to save memory. (1 -> decodes full size; 2 -> decodes 1/4th size; 4 -> decode 1/16th size). Because you rarely need to show and have full size bitmap images on your phone. For manipulations smaller sizes are usually enough.inJustDecodeBounds为Boolean型设置inJustDecodeBounds为true后,decodeFile并不分配空间,但可计算出原始图片的长度和宽度,即options.outWidth和options.outHeight。

要对图片进行缩放,最大的问题就是怎么在运行时动态的改变inSampleSize的值,通过上面的inJustDecodeBounds可以知道图片原始的大小,那么这样以来就可以通过算法来得到一个恰当的inSampleSize值。

什么是OOM?为什么会出现OOM?

什么是OOM?为什么会出现OOM?

一、OOM含义:OOM,全称“OutOfMemory”,意思是“内存用完了”。

它来源于ng.OutOfMemoryError。

二、为什么会出现ng.OutOfMemoryError:即OOM:官方介绍为当JVM因为没有足够的内存来为对象分配空间并且垃圾回收器也已经没有空间可回收时,就会抛出ng.OutOfMemoryError:···(注意:这是个很严重的问题,因为这个问题已经严重到不足以被应用处理)。

具体原因大致为两方面:1、自身原因:比如虚拟机本身可使用的内存太少。

2、外在原因:如应用使用的太多,且用完没释放,浪费了内存。

此时就会造成内存泄露或者内存溢出。

内存泄露:申请使用完的内存没有释放,导致虚拟机不能再次使用该内存,此时这段内存就泄露了,因为申请者不用了,而又不能被虚拟机分配给别人用。

内存溢出:申请的内存超出了JVM能提供的内存大小,此时称之为溢出。

三、OOM的error类型首先说一下JAVA虚拟机运行时会管理的内存区域吧:1.程序计数器:当前线程执行的字节码的行号指示器,线程私有2.JAVA虚拟机栈:Java方法执行的内存模型,每个Java方法的执行对应着一个栈帧的进栈和出栈的操作。

3.本地方法栈:类似“JAVA虚拟机栈”,但是为native方法的运行提供内存环境。

4.JAVA堆:对象内存分配的地方,内存垃圾回收的主要区域,所有线程共享。

可分为新生代,老生代。

5.方法区:用于存储已经被JVM加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

Hotspot中的“永久代”。

6.运行时常量池:方法区的一部分,存储常量信息,如各种字面量、符号引用等。

7.直接内存:并不是JVM运行时数据区的一部分,可直接访问的内存,比如NIO会用到这部分。

所以除了程序计数器不会抛出OOM外,其他各个内存区域都可能会抛出OOM。

常见OOM情况:ng.OutOfMemoryError:Javaheapspace------>java堆内存溢出,此种情况最常见,一般由于内存泄露或者堆的大小设置不当引起。

out of memory修复方法

out of memory修复方法

Out of Memory修复方法什么是Out of Memory错误?Out of Memory(OOM)是一种常见的计算机错误,指的是在程序运行过程中,由于系统内存不足,无法分配更多内存导致程序崩溃。

当程序尝试申请更多内存时,操作系统无法满足其需求,触发了Out of Memory错误。

Out of Memory错误可能在任何程序中发生,无论是操作系统内核还是应用程序。

当系统内存消耗殆尽时,操作系统会尝试通过终止某些进程来为正在运行的程序释放内存,但在某些情况下,这可能无法挽救程序的崩溃。

Out of Memory错误的原因Out of Memory错误的原因可能有多种。

以下是一些常见的原因:1.内存泄漏:当程序分配内存后,但没有释放时,会导致内存泄漏。

如果内存泄漏发生频繁或泄漏量很大,最终会导致系统内存不足,触发Out of Memory错误。

2.程序设计缺陷:某些程序设计缺陷可能导致内存使用不当,例如无限循环、递归调用等。

这些问题可能导致程序无限消耗内存,最终导致系统内存不足。

3.资源竞争:当多个程序或线程同时竞争有限的内存资源时,可能会导致Out of Memory错误。

这种情况通常发生在多任务环境中,当多个任务同时试图占用系统内存时,操作系统可能无法满足所有任务的需求。

Out of Memory修复方法解决Out of Memory错误的方法取决于原因。

以下是一些常见的修复方法:1. 识别和修复内存泄漏内存泄漏是Out of Memory错误的常见原因之一。

识别和修复内存泄漏非常重要。

以下是一些可能的方法:•使用性能分析工具:使用性能分析工具来检测内存泄漏。

这些工具可以帮助您找到哪些对象没有被准确地释放,并追踪它们的引用路径。

•代码审查:仔细审查代码,查找可能导致内存泄漏的地方。

例如,确保在适当的时候释放动态分配的内存,避免不必要的全局变量等。

•使用合适的内存管理技术:根据编程语言和平台的不同,选择合适的内存管理技术。

Android内存使用研究

Android内存使用研究

Android 内存使用研究众所周知,在写 android 程序的时候,很容易出现 OOM ,而出现的时机大多数是由 Bitmap decode 引发的:1 ERROR/AndroidRuntime(16350): ng.OutOfMemoryError: bitmap size exceeds VM budget我们知道,android 程序内存一般限制在16M ,当然也有24M 的,而android 程序内存被分为2部分:native 和dalvik :dalvik 就是我们平常说的java 堆,我们创建的对象是在这里面分配的,而bitmap 是直接在native 上分配的,对于内存的限制是native+dalvik 不能超过最大限制。

注:一旦内存分配给Java 后,以后这块内存纵然开释后,也只能给Java 的施用,这个估计跟java 虚拟机里把内存分成好几块进行缓存的原因有关,反正C 就别想用到这块的内存了,所以要是Java 突然占用了一个大块内存,纵然很快开释了:C 能施用的内存 = 16M - Java 某一瞬间占用的最大内存。

而Bitmap 的生成是通过malloc 进行内存分配的,占用的是C 的内存,这个也就说明了,上面所说的的4MBitmap 无法生成的原因,因为在13M 被Java 用过后,剩下C 能用的只有3M 了。

用以下命令可以查看程序的内存使用情况:adb shell dumpsysmeminfopackagename orpid 程序的包名或者进程id其中size是需要的内存,而allocated是分配了的内存,对应的2列分别是native和dalvik,当总数也就是total这一列超过单个程序内存的最大限制时,OOM就很有可能会出现了。

多数时候,发生OOM 都是在做一些跟图片相关的操作,以下提出一些建议尽量可以减少这种情况的发生:1 .decode bitmap 的时候,尽量配置下Options,例如:inSameSize2 .Bitmap使用完以后,调用 bitmap.recycle()来释放内存3 .如果应用是基于图片的应用,尽量采用LazyLoad和DymanicRecycle4.decode bitmap 的时候,将decode代码 try catch 出来,catch oom error,避免程序crash,可以在catch里面做一些释放内存操作关于Android的Native内存和Dalvik内存1.Dalvik内存每一个Android应用在底层都会对应一个独立的Dalvik虚拟机实例,其代码在虚拟机的解释下得以执行。

Android开发OOM异常

Android开发OOM异常

Android开发中如何避免OOM异常?翡翠教育-Android开发培训1、加载图片对内存的影响在Android开发中,加载图片很容易的碰到OOM。

何为OOM? OOM, 即out of memory,这里面的memory指的是堆内存。

因为在Android中,应用程序都是有一定的内存限制的。

当内存占用过高就容易出现OOM异常。

我们可以通过下面的代码看出每个应用程序最高可用内存是多少:那为什么要特别重视图片内存的占用呢?我们来看一下一张图片能占多少内存吧。

举个例子,当我们加载一张分辨率为1960*1200,色彩模式为ARGB_8888,图片大小为4M的图片时,其所占用的内存空间并不是图片的大小,而是根据图片的分辨率来计算的。

这张图片需要的内存为:1960*1200*4(bit) / 1024 / 1024 = 8.79MB一张图片就占用了将近9M,如果是一组图片呢?可以想象的到,如果我们在加载图片的时候使用原图加载的话,程序分分钟就死掉了。

因此,在展示高分辨率图片的时候,最好先将图片进行压缩。

压缩后的图片大小应该和用来展示它的控件大小相近,毕竟在一个很小的ImageView上显示一张超大的图片不会带来任何视觉上的好处,但却会占用我们相当多宝贵的内存,而且在性能上还可能会带来负面影响。

2、降低图片内存占用——压缩图片从上节来看,影响一张图片占用内存的有两方面的因素,(1)压缩尺寸(2)色彩模式;从色彩模式的角度,对于一个ARGB_8888的图片,在满足业务需求的情况下,比如并不要求这张图片特别清晰逼真,那么可以在压缩尺寸之前,可以同时将option的值重新设置一下,比如设置为RGB_565。

ARGB_8888,表示一个像素占8+8+8+8=32位=4字节,而RGB_565,表示一个像素占用5+6+5=16位=2字节。

这样设置之后图片内存占用会减半。

下面重点来看一下尺寸方面的压缩。

如何对一张大图片进行适当的压缩,让它能够以最佳大小显示的同时,还能防止OOM的出现。

OOM解决方案

OOM解决方案

OOM解决⽅案⼀、什么是OOM OutOfMemory(内存溢出)就是内存⽤完了,意思就是说,当JVM因为没有⾜够的内存来为对象分配空间并且垃圾回收器也已经没有空间可回收时,就会抛出这个error(注:⾮exception,因为这个问题已经严重到不⾜以被应⽤处理)。

PS.⼀个线程OOM,进程⾥其他线程还能运⾏吗?⼀个线程溢出后,进程⾥的其他线程还能照常运⾏,当⼀个线程抛出OOM异常后,它所占据的内存资源会全部被释放掉,从⽽不会影响其他线程的运⾏。

⼆、OOM产⽣原因1. 分配的少了:⽐如虚拟机本⾝可使⽤的内存(⼀般通过启动时的VM参数指定)太少。

2. 应⽤⽤的太多,并且⽤完没释放,浪费了。

此时就会造成内存泄露或者内存溢出。

三、OOM类型 1.永久区溢出:ng.OutOfMemoryError: PermGen space这⼀部分⽤于存放Class和Meta的信息,Class在被 Load的时候被放⼊PermGen space区域(包括常量池: 静态变量),它和存放Instance的Heap区域不同,GC(Garbage Collection)不会在主程序运⾏期对PermGen space进⾏清理,所以如果你的APP会LOAD很多CLASS的话,就很可能出现PermGen space错误。

这种错误常见在web服务器对JSP进⾏pre compile的时候。

可以通过设置jvm启动参数来解决:-XX:MaxPermSize=256m 2. 堆溢出 ng.OutOfMemoryError: Java heap space 这部分⽤于存放类的实例。

被缓存的实例(Cache)对象,⼤的map,list引⽤⼤的对象等等,都会保存于此,过期引⽤可能会导致堆溢出。

堆内存会在jvm启动时⾃动设置,初始值 -Xms为物理内存的1/64,最⼤值-Xmx为1/4;可以通过参数-Xmn、-Xms、-Xmx设置,⼀般-Xms和-Xmx不超过80%,-Xmn为-Xmx的1/4; 3.栈溢出: Exception in thread "main" ng.StackOverflowError 这部分⽤于存放局部变量、⽅法栈帧信息。

Android中bitmap引起内存溢出的解决方案的对比分析

Android中bitmap引起内存溢出的解决方案的对比分析

Android中bitmap引起内存溢出的解决方案的对比分析摘要Android手机在系统加载多个图片和大图片会耗费大量内存,就位图(bitmap)而言,假如其内存占用超过了一定数值,就会出现OutOfMemory(内存溢出)错误。

当前对于该错误的解决方案多且杂,没有统一定论。

笔者进行了广泛的搜集,归纳出当下主流的五种解决方案,并用程序对它们进行对比分析、评估,以便针对不同情况选择最优的解决方案。

关键词Android;bitmap;内存溢出0引言Android系统是基于Linux平台的、开源的、智能手机操作系统。

如图1所示,Android系统由下往上分为四个层次:1)Linux内核;2)类库和Android 运行环境,Android运行环境又包括核心库和Dalvik VM(Dalvik虚拟机);3)应用程序框架;4)应用程序。

Java的编写程序在的Android的相关内存程序中运用的,这就表现出在应用上它们之间是相融,相似。

即采用Garbage Collector (垃圾回收器)机制,由运行时环境来自动管理内存。

在程序上存在着引用和被引用,在基础引用的部分同称为活对象,没有实行用到的为垃圾对象,在垃圾对象中并使用回收效益在collector是一个重要的工作,这样的操作名称为GC (Garbage Collection,垃圾回收),是由Dalvik VM负责的。

图1 Android系统架构图位图(bitmap),是由称作像素的单个点组成的。

bitmap文件图像效果虽好,但采用非压缩格式,需要占用较大的存储空间。

Android的虚拟机是基于寄存器的Dalvik,它的最大堆大小一般是16M,也有少数为24M,内存空间十分有限。

随着移动互联网技术的进步,大量的APP都会使用分辨率较高的图片,而Android 开发者在从事与图片相关的软件开发时,几乎都会遇到内存溢出问题。

不少开发者在网上分享了自己的解决方法,当下主流的解决方案有四种:1)等比例缩小bitmap;2)采用SoftReference(软引用);3)及时回收内存;4)优化Dalvik VM 的堆内存分配。

引起OOM的一些简单原因及应对方案

引起OOM的一些简单原因及应对方案

引起OOM的⼀些简单原因及应对⽅案Android oom 有时出现很频繁,这⼀般不是Android设计的问题,⼀般是我们的问题。

就我的经验⽽⾔,出现oom,⽆⾮主要是以下⼏个⽅⾯: ⼀、加载对象过⼤ ⼆、相应资源过多,没有来不及释放。

解决这样的问题,也有⼀下⼏个⽅⾯: ⼀:在内存引⽤上做些处理,常⽤的有软引⽤、强化引⽤、弱引⽤ ⼆:在内存中加载图⽚时直接在内存中做处理,如:边界压缩. 三:动态回收内存 四:优化Dalvik虚拟机的堆内存分配 五:⾃定义堆内存⼤⼩ 可真有这么简单吗,不见得,看我娓娓道来: 软引⽤(SoftReference)、虚引⽤(PhantomRefrence)、弱引⽤(WeakReference),这三个类是对heap中java对象的应⽤,通过这个三个类可以和gc做简单的交互,除了这三个以外还有⼀个是最常⽤的强引⽤. 强引⽤,例如下⾯代码: Object o=new Object(); Object o1=o; 上⾯代码中第⼀句是在heap堆中创建新的Object对象通过o引⽤这个对象,第⼆句是通过o建⽴o1到new Object()这个heap堆中的对象的引⽤,这两个引⽤都是强引⽤.只要存在对heap中对象的引⽤,gc就不会收集该对象.如果通过如下代码: o=null; o1=null; heap中对象有强可及对象、软可及对象、弱可及对象、虚可及对象和不可到达对象。

应⽤的强弱顺序是强、软、弱、和虚。

对于对象是属于哪种可及的对象,由他的最强的引⽤决定。

如下:String abc=new String("abc"); //1SoftReference<String> abcSoftRef=new SoftReference<String>(abc); //2WeakReference<String> abcWeakRef = new WeakReference<String>(abc); //3abc=null; //4abcSoftRef.clear();//5在此例中,透过 get() 可以取得此 Reference 的所指到的对象,如果返回值为 null 的话,代表此对象已经被清除。

android 处理图片内存溢出 VM

android 处理图片内存溢出 VM

使用android提供的BitmapFactory解码一张图片时,有时会遇到该错误,即:ng.OutOfMemoryError: bitmap size exceeds VM budget。

这往往是由于图片过大造成的。

要想正常使用,一种方式是分配更少的内存空间来存储,即在载入图片的时候以牺牲图片质量为代价,将图片进行放缩,这也是不少人现在为避免以上的OOM所采用的解决方法。

但是,这种方法是得不偿失的,当我们使用图片作为缩略图查看时候倒是没有说什么,但是,当需要提供图片质量的时候,该怎么办呢?ng.OutOfMemoryError: bitmap size exceeds VM budget着实让不少人欲哭无泪呀!前几天刚好有个需求需要载入SD卡上面的图片。

首先是使用Bitmap bmp =BitmapFactory.decodeFile(pePicFile.getAbsolutePath() + "/"+info.getImage());上面参数是我将要读取的图片文件及路径,当文件较小时,程序能够正常运行,但是当我选择一张大图时,程序立刻蹦出了ng.OutOfMemoryError: bitmap size exceeds VM budget的OOM错误!在android设备上(where you have only 16MB memory available),如果使用BitmapFactory解码一个较大文件,很大的情况下会出现上述情况。

那么,怎么解决?!先说之前提到过的一种方法:即将载入的图片缩小,这种方式以牺牲图片的质量为代价。

在BitmapFactory中有一个内部类BitmapFactory.Options,其中当options.inSampleSize值>1时,根据文档:If set to a value > 1, requests the decoder to subsample the original image, returning a smaller image to save memory. (1 -> decodes full size;2 -> decodes 1/4th size; 4 -> decode 1/16th size). Because you rarely need to show and have full size bitmap images on your phone. For manipulations smaller sizes are usually enough.也就是说,options.inSampleSize是以2的指数的倒数被进行放缩。

android_内存溢出处理

android_内存溢出处理

昨天在模拟器上给gallery放入图片的时候,出现ng.OutOfMemoryError: bitmap size exceeds VM budget 异常,图像大小超过了RAM内存。

模拟器RAM比较小,只有8M内存,当我放入的大量的图片(每个100多K左右),就出现上面的原因。

由于每张图片先前是压缩的情况,放入到Bitmap的时候,大小会变大,导致超出RAM内存,具体解决办法如下://解决加载图片内存溢出的问题//Options 只保存图片尺寸大小,不保存图片到内存BitmapFactory.Options opts = new BitmapFactory.Options();//缩放的比例,缩放是很难按准备的比例进行缩放的,其值表明缩放的倍数,SDK中建议其值是2的指数值,值越大会导致图片不清晰opts.inSampleSize = 4;Bitmap bmp = null;bmp = BitmapFactory.decodeResource(getResources(), mImageIds[position],opts);...//回收bmp.recycle();通过上面的方式解决了,但是这并不是最完美的解决方式。

通过一些了解,得知如下:优化Dalvik虚拟机的堆内存分配对于Android平台来说,其托管层使用的Dalvik Java VM从目前的表现来看还有很多地方可以优化处理,比如我们在开发一些大型游戏或耗资源的应用中可能考虑手动干涉GC处理,使用dalvik.system.VMRuntime类提供的setTargetHeapUtilization方法可以增强程序堆内存的处理效率。

当然具体原理我们可以参考开源工程,这里我们仅说下使用方法: private final static float TARGET_HEAP_UTILIZATION = 0.75f; 在程序onCreate时就可以调用VMRuntime.getRuntime().setTargetHeapUtilization(TARGET_HEAP_UTILIZATION); 即可。

几种outofmemory的解决方法

几种outofmemory的解决方法

几种outofmemory的解决方法Out of Memory(内存溢出)是指应用程序在运行过程中尝试申请的内存量超出了系统所能提供的最大内存限制。

当应用程序无法获取所需的内存空间时,会导致程序崩溃或出现异常。

为了解决 Out of Memory 的问题,可以采取以下几种方法:1. 检查内存泄漏:内存泄漏是指程序中分配的内存没有得到释放,导致内存占用不断增加。

通过使用内存分析工具,如 Java VisualVM、Eclipse Memory Analyzer等,可以检测到内存泄漏的问题并进行修复。

2. 增加堆内存:可以通过修改应用程序的启动参数,增加 Java 虚拟机(JVM)的堆内存大小。

通过修改 -Xmx 参数,可以增加最大堆内存的大小,例如将 -Xmx 设置为 2GB,即可将最大堆内存增加到 2GB。

3.优化代码逻辑:检查应用程序的代码逻辑,确保不会产生无限循环、重复创建对象等导致内存消耗过大的问题。

例如,可以使用缓存对象、避免频繁创建临时对象等方式来减少内存的使用。

4.使用内存分页:可以将内存中的数据分页加载,将数据分为多个页面进行处理,每次只加载当前需要的页面。

这样可以减少一次性加载大量数据造成的内存压力。

5. 使用软引用或弱引用:软引用和弱引用是 Java 中的两种特殊引用类型,它们可以在内存不足时自动释放被引用对象的内存空间。

通过使用软引用或弱引用,可以减少内存的消耗。

6.使用内存缓存:将经常使用的数据缓存在内存中,避免频繁的磁盘读写操作。

通过使用内存缓存,可以提高数据的读取速度,并减少对物理内存的消耗。

7.分析内存使用情况:使用工具分析内存使用情况,找出内存占用过多的原因。

通过监控内存使用情况,可以发现内存泄漏、内存占用过大的问题,并进行及时的优化。

8.压缩数据:对于大量的数据存储,可以采取数据压缩的方式来减少内存的消耗。

例如,使用压缩算法对图片、文件等数据进行压缩,可以减少内存的使用量。

ANDROID BITMAP内存限制OOM,OUT OF MEMORY

ANDROID BITMAP内存限制OOM,OUT OF MEMORY

ANDROID BITMAP内存限制OOM OUT OF MEMORY在编写Android程序的时候,我们总是难免会碰到OOM的错误,那么这个错误究竟是怎么来的呢?我们先来看一下这段异常信息:08-14 05:15:04.764: ERROR/dalvikvm-heap(264): 3528000-byte external allocation too large for this process.08-14 05:15:04.764: ERROR/(264): VM won't let us allocate 3528000 bytes08-14 05:15:04.764: DEBUG/skia(264): --- decoder->decode returned false08-14 05:15:04.774: DEBUG/AndroidRuntime(264): Shutting down VM08-14 05:15:04.774: WARN/dalvikvm(264): threadid=3: thread exiting with uncaught exception (group=0x4001b188)08-14 05:15:04.774: ERROR/AndroidRuntime(264): Uncaught handler: thread main exiting due to uncaught exception08-14 05:15:04.794: ERROR/AndroidRuntime(264): ng.OutOfMemoryError: bitmap size exceeds VM budget08-14 05:15:04.794: ERROR/AndroidRuntime(264): at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)08-14 05:15:04.794: ERROR/AndroidRuntime(264): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:447)08-14 05:15:04.794: ERROR/AndroidRuntime(264): at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:323) 08-14 05:15:04.794: ERROR/AndroidRuntime(264): at android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:346)08-14 05:15:04.794: ERROR/AndroidRuntime(264): at android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:372)08-14 05:15:04.794: ERROR/AndroidRuntime(264): at com.xixun.test.HelloListView.onCreate(HelloListView.java:33)08-14 05:15:04.794: ERROR/AndroidRuntime(264): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)08-14 05:15:04.794: ERROR/AndroidRuntime(264): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2459)08-14 05:15:04.794: ERROR/AndroidRuntime(264): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2512)08-14 05:15:04.794: ERROR/AndroidRuntime(264): at android.app.ActivityThread.access$2200(ActivityThread.java:119)08-14 05:15:04.794: ERROR/AndroidRuntime(264): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1863)08-14 05:15:04.794: ERROR/AndroidRuntime(264): at android.os.Handler.dispatchMessage(Handler.java:99)08-14 05:15:04.794: ERROR/AndroidRuntime(264): at android.os.Looper.loop(Looper.java:123)08-14 05:15:04.794: ERROR/AndroidRuntime(264): at android.app.ActivityThread.main(ActivityThread.java:4363)08-14 05:15:04.794: ERROR/AndroidRuntime(264): at ng.reflect.Method.invokeNative(Native Method)08-14 05:15:04.794: ERROR/AndroidRuntime(264): at ng.reflect.Method.invoke(Method.java:521)08-14 05:15:04.794: ERROR/AndroidRuntime(264): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860) 08-14 05:15:04.794: ERROR/AndroidRuntime(264): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)08-14 05:15:04.794: ERROR/AndroidRuntime(264): at dalvik.system.NativeStart.main(Native Method)从上面这段异常信息中,我们看到了一个OOM(OutOfMemory)错误,我称其为(OMG错误)。

应对Android测试中的各种异常情况

应对Android测试中的各种异常情况

应对Android测试中的各种异常情况在Android测试中,经常会面临各种各样的异常情况。

这些异常情况可能会导致应用程序崩溃、功能失效或者测试结果不准确。

为了保证测试的完整性和准确性,我们需要有一套有效的应对措施来处理这些异常情况。

以下是我总结的一些应对Android测试中各种异常情况的方法:一、OOM(Out of Memory)异常OOM异常在Android开发和测试中是非常常见的。

它通常发生在内存资源不足时,导致应用程序无法继续正常执行。

为了应对这种异常情况,我们可以采取以下措施:1. 检查内存泄露:使用工具(如LeakCanary)来检测应用程序中的内存泄露问题,及时修复这些问题。

2. 内存优化:尽量减少不必要的内存占用,如使用适当的数据结构、避免加载大量的图片资源等。

二、ANR(Application Not Responding)异常ANR异常是指当应用程序无响应超过一定时间(通常为5秒),系统会弹出ANR对话框,提示用户应用程序停止响应。

为了避免ANR异常的发生,我们可以采取以下措施:1. 尽量减少后台线程的运行时间:避免在主线程内执行耗时操作,通过使用异步任务或者后台线程来执行这些操作。

2. 优化UI线程的响应时间:减少UI线程的负载,避免进行耗时的操作,如加载大量图片或者进行复杂的计算等。

三、网络异常网络异常可能会导致应用程序无法正常访问网络资源,或者请求超时等问题。

为了应对这种异常情况,我们可以采取以下措施:1. 检查网络连接状态:在进行网络请求前,先检查网络连接状态,如果没有网络连接,则给出适当的提示信息给用户。

2. 添加超时机制:在进行网络请求时,设置适当的超时时间,如果请求超过了指定的时间还没有返回结果,可以进行重试或者给出相关提示信息。

四、设备兼容性问题Android平台的设备种类繁多,设备的硬件和系统版本也各不相同,因此在测试过程中可能会出现设备兼容性问题。

为了解决这种异常情况,我们可以采取以下措施:1. 多设备测试:在进行测试时,尽量涵盖不同类型的Android设备,包括不同的品牌、型号和系统版本。

oom的解决方案

oom的解决方案

oom的解决方案
《解决OOM问题的方法》
OOM(Out of Memory)是指在计算机系统中由于内存不足而导致的程序异常终止的问题。

当程序请求的内存超出系统实际可用的内存空间时,系统就会报OOM错误,导致程序崩溃。

解决OOM问题对于保障系统的稳定运行至关重要,下面介绍一些解决OOM问题的方法。

首先,可以通过增加系统内存来解决OOM问题。

内存不足是导致OOM的主要原因之一,增加系统内存可以有效减轻OOM问题的发生。

可以通过增加物理内存条或者利用虚拟化技术来扩展系统内存。

其次,对于出现OOM问题的程序,可以通过优化程序代码来解决。

比如在编程中尽量避免内存泄露、减少内存占用等方式来优化程序。

另外,还可以通过优化程序的缓存管理、资源释放等方面来减少OOM的发生。

此外,可以通过调整系统的内存参数来解决OOM问题。

比如调整JVM的堆内存大小、调整系统的内核参数等方式来优化系统内存的使用。

可以根据系统的实际情况来调整参数,以达到提高系统性能的目的。

最后,可以通过进程监控工具来及时发现并处理OOM问题。

一旦出现OOM问题,可以通过进程监控工具来及时发现并处理问题,以减少系统不稳定性对业务的影响。

总之,解决OOM问题需要综合考虑系统内存大小、程序优化、系统调优等多个方面,只有综合考虑并采取相应的措施,才能有效减少OOM问题的发生。

希望以上介绍的方法可以对解决OOM问题有所帮助。

oom 内存溢出的排查思路

oom 内存溢出的排查思路

oom 内存溢出的排查思路以OOM(Out of Memory)内存溢出的排查思路为标题,我们将从以下几个方面来探讨如何解决这个问题。

1. 理解OOM内存溢出的原因OOM内存溢出是指应用程序在申请内存时,无法获得足够的内存空间而导致的错误。

这可能是因为应用程序的内存使用超过了系统分配给它的内存限制,或者是由于内存泄漏等问题导致的。

理解OOM的原因对于解决问题至关重要。

2. 分析错误日志在遇到OOM内存溢出问题时,首先应该分析错误日志。

错误日志通常会提供有关错误发生的位置、异常堆栈信息以及导致问题的原因的线索。

通过仔细阅读错误日志,可以确定问题的具体来源,并为解决问题提供指导。

3. 检查代码中的内存泄漏内存泄漏是导致OOM内存溢出的常见原因之一。

在排查问题时,需要仔细检查应用程序的代码,查找可能存在的内存泄漏点。

内存泄漏通常是由于未正确释放对象或者对象的生命周期管理不当导致的。

通过分析代码,可以找到潜在的内存泄漏点,并进行修复。

4. 检查内存使用情况除了检查代码中的内存泄漏,还应该对应用程序的内存使用情况进行监控和分析。

可以通过使用内存分析工具来获取应用程序的内存快照,并查看内存中存在的对象、其大小以及引用关系等信息。

通过对内存使用情况的分析,可以找到内存占用较大的对象,进一步缩小问题的范围。

5. 调整内存配置参数在一些情况下,OOM内存溢出可能是由于应用程序的内存配置参数设置不合理导致的。

例如,堆内存大小设置过小,无法满足应用程序的需求。

在排查问题时,可以尝试调整内存配置参数,增加堆内存大小或者调整垃圾回收算法等。

通过适当调整内存配置参数,可以有效地缓解或解决OOM内存溢出问题。

6. 优化代码和算法除了修复内存泄漏和调整内存配置参数外,还可以通过优化代码和算法来降低应用程序的内存占用。

例如,可以减少对象的创建和销毁次数,尽量复用对象,避免使用过多的静态变量等。

通过优化代码和算法,可以减少内存占用,提高应用程序的性能和稳定性。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

ANDROID BITMAP内存限制OOM OUT OF MEMORY在编写Android程序的时候,我们总是难免会碰到OOM的错误,那么这个错误究竟是怎么来的呢?我们先来看一下这段异常信息:08-14 05:15:04.764: ERROR/dalvikvm-heap(264): 3528000-byte external allocation too large for this process.08-14 05:15:04.764: ERROR/(264): VM won't let us allocate 3528000 bytes08-14 05:15:04.764: DEBUG/skia(264): --- decoder->decode returned false08-14 05:15:04.774: DEBUG/AndroidRuntime(264): Shutting down VM08-14 05:15:04.774: WARN/dalvikvm(264): threadid=3: thread exiting with uncaught exception (group=0x4001b188)08-14 05:15:04.774: ERROR/AndroidRuntime(264): Uncaught handler: thread main exiting due to uncaught exception08-14 05:15:04.794: ERROR/AndroidRuntime(264): ng.OutOfMemoryError: bitmap size exceeds VM budget08-14 05:15:04.794: ERROR/AndroidRuntime(264): at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)08-14 05:15:04.794: ERROR/AndroidRuntime(264): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:447)08-14 05:15:04.794: ERROR/AndroidRuntime(264): at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:323) 08-14 05:15:04.794: ERROR/AndroidRuntime(264): at android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:346)08-14 05:15:04.794: ERROR/AndroidRuntime(264): at android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:372)08-14 05:15:04.794: ERROR/AndroidRuntime(264): at com.xixun.test.HelloListView.onCreate(HelloListView.java:33)08-14 05:15:04.794: ERROR/AndroidRuntime(264): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)08-14 05:15:04.794: ERROR/AndroidRuntime(264): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2459)08-14 05:15:04.794: ERROR/AndroidRuntime(264): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2512)08-14 05:15:04.794: ERROR/AndroidRuntime(264): at android.app.ActivityThread.access$2200(ActivityThread.java:119)08-14 05:15:04.794: ERROR/AndroidRuntime(264): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1863)08-14 05:15:04.794: ERROR/AndroidRuntime(264): at android.os.Handler.dispatchMessage(Handler.java:99)08-14 05:15:04.794: ERROR/AndroidRuntime(264): at android.os.Looper.loop(Looper.java:123)08-14 05:15:04.794: ERROR/AndroidRuntime(264): at android.app.ActivityThread.main(ActivityThread.java:4363)08-14 05:15:04.794: ERROR/AndroidRuntime(264): at ng.reflect.Method.invokeNative(Native Method)08-14 05:15:04.794: ERROR/AndroidRuntime(264): at ng.reflect.Method.invoke(Method.java:521)08-14 05:15:04.794: ERROR/AndroidRuntime(264): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860) 08-14 05:15:04.794: ERROR/AndroidRuntime(264): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)08-14 05:15:04.794: ERROR/AndroidRuntime(264): at dalvik.system.NativeStart.main(Native Method)从上面这段异常信息中,我们看到了一个OOM(OutOfMemory)错误,我称其为(OMG错误)。

出现这个错误的原因是什么呢?为什么解码图像会出现这样的问题呢?关于这个问题,我纠结了一段时间,在网上查询了很多资料,甚至查看了Android Issues,确实看到了相关的问题例如Issue 3405,Issue 8488,尤其Issue 8488下面一楼的回复,让我觉得很雷人啊:Comment 1 by romain...@, May 23, 2010Your app needs to use less memory.当然我们承认不好的程序总是程序员自己错误的写法导致的,不过我们倒是非常想知道如何来规避这个问题,那么接下来就是解答这个问题的关键。

我们从上面的异常堆栈信息中,可以看出是在BitmapFactory.nativeDecodeAsset(),对应该方法的native方法是在BitmapFactory.cpp中的doDecode()方法,在该方法中申请JavaPixelAllocator对象时,会调用到Graphics.cpp中的setJavaPixelRef()方法,在setJavaPixelRef()中会对解码需要申请的内存空间进行一个判断,代码如下:bool r = env->CallBooleanMethod(gVMRuntime_singleton,gVMRuntime_trackExternalAllocationMethodID,jsize);而JNI方法ID -- gVMRuntime_trackExternalAllocationMethodID对应的方法实际上是dalvik_system_VMRuntime.c中的Dalvik_dalvik_system_VMRuntime_trackExternalAllocation(),而在该方法中又会调用大HeapSource.c中的dvmTrackExternalAllocation()方法,继而调用到externalAllocPossible()方法,在该方法中这句代码是最关键的heap = hs2heap(hs);currentHeapSize = mspace_max_allowed_footprint(heap->msp);if (currentHeapSize + hs->externalBytesAllocated + n <=heap->absoluteMaxSize){return true;}这段代码的意思应该就是当前堆已使用的大小(由currentHeapSize和hs->externalBytesAllocated构成)加上我们需要再次分配的内存大小不能超过堆的最大内存值。

那么一个堆的最大内存值究竟是多大呢。

通过下面这张图,我们也许可以看到一些线索(自己画的,比较粗糙)最终的决定权其实是在Init.c中,因为Android在启动系统的时候会去优先执行这个里面的函数,通过调用dvmStartup()方法来初始化虚拟机,最终调用到会调用到HeapSource.c中的dvmHeapSourceStartup()方法,而在Init.c中有这么两句代码:gDvm.heapSizeStart = 2 * 1024 * 1024; // Spec says 16MB; too big for us.gDvm.heapSizeMax = 16 * 1024 * 1024; // Spec says 75% physical mem在另外一个地方也有类似的代码,那就是AndroidRuntime.cpp中的startVM()方法中:strcpy(heapsizeOptsBuf, "-Xmx");property_get("dalvik.vm.heapsize", heapsizeOptsBuf+4, "16m");//LOGI("Heap size: %s", heapsizeOptsBuf);opt.optionString = heapsizeOptsBuf;同样也是默认值为16M,虽然目前我看到了两个可以启动VM的方法,具体Android何时会调用这两个初始化VM的方法,还不是很清楚。

相关文档
最新文档