Gre*_*reg 30 android out-of-memory android-bitmap
我一直在做很多搜索,我知道很多其他人都遇到了同样的OOM内存问题BitmapFactory.我的应用程序仅显示可用的4MB内存总量Runtime.getRuntime
().totalMemory().如果限制是16MB,那么为什么总内存不会增长以便为位图腾出空间呢?相反,它会抛出错误.
我也不明白,如果我有1.6MB的可用内存,根据Runtime.getRuntime().freeMemory()为什么我会收到错误说"VM不会让我们分配614400字节"?在我看来,我有足够的可用内存.
我的应用程序是完整的,除了这个问题,当我重新启动手机时,它会消失,以便我的应用程序是唯一运行的东西.我正在使用HTC Hero进行设备测试(Android 1.5).
在这一点上,我认为解决这个问题的唯一方法是以某种方式避免使用BitmapFactory.
任何人对此有任何想法或解释为什么当1.6MB的可用内存时VM不会分配614KB?
Tor*_*rid 46
[注意(如下面CommonsWare所述)此答案中的整个方法仅适用于2.3.x(Gingerbread).从Honeycomb开始,Bitmap数据在VM堆中分配.
位图数据未在VM堆中分配.VM堆中有一个引用(很小),但实际数据由底层Skia图形库在Native堆中分配.
不幸的是,虽然BitmapFactory.decode ...()的定义说如果图像数据无法解码它返回null,Skia实现(或者更确切地说是Java代码和Skia之间的JNI粘合剂)会记录您的消息看到("VM不会让我们分配xxxx字节")然后使用误导性消息"位图大小超过VM预算"抛出OutOfMemory异常.
问题不在VM堆中,而是在Native堆中.Natïve堆在运行的应用程序之间共享,因此可用空间量取决于正在运行的其他应用程序及其位图使用情况.但是,鉴于BitmapFactory不会返回,您需要一种方法来确定在调用之前调用是否会成功.
有一些例程可以监视Native堆的大小(请参阅Debug类的getNative方法).但是,我发现getNativeHeapFreeSize()和getNativeHeapSize()不可靠.因此,在我的一个动态创建大量位图的应用程序中,我执行以下操作.
Native堆大小因平台而异.因此,在启动时,我们检查允许的最大VM堆大小,以确定允许的最大本机堆大小.[神奇的数字是通过测试2.1和2.2来确定的,并且在其他API级别上可能会有所不同.]
long mMaxVmHeap = Runtime.getRuntime().maxMemory()/1024;
long mMaxNativeHeap = 16*1024;
if (mMaxVmHeap == 16*1024)
mMaxNativeHeap = 16*1024;
else if (mMaxVmHeap == 24*1024)
mMaxNativeHeap = 24*1024;
else
Log.w(TAG, "Unrecognized VM heap size = " + mMaxVmHeap);
Run Code Online (Sandbox Code Playgroud)
然后每当我们需要调用BitmapFactory时,我们会在调用之前检查表单.
long sizeReqd = bitmapWidth * bitmapHeight * targetBpp / 8;
long allocNativeHeap = Debug.getNativeHeapAllocatedSize();
if ((sizeReqd + allocNativeHeap + heapPad) >= mMaxNativeHeap)
{
// Do not call BitmapFactory…
}
Run Code Online (Sandbox Code Playgroud)
请注意,heapPad是一个神奇的数字,它允许以下事实:a)本机堆大小的报告是"软"的; b)我们希望在Native堆中为其他应用程序留出一些空间.我们目前正在运行3*1024*1024(即3Mbytes)的打击垫.
1.6 MB 的内存看起来很多,但也可能是内存碎片严重,无法一次性分配这么大的内存块(这听起来确实很奇怪)。
使用图像资源时出现 OOM 的常见原因之一是解压缩具有非常高分辨率的 JPG、PNG、GIF 图像。您需要记住,所有这些格式都经过很好的压缩,占用的空间非常小,但是一旦您将图像加载到手机上,它们将使用的内存类似于width * height * 4 bytes. 此外,当解压缩开始时,需要加载一些其他辅助数据结构以进行解码步骤。
| 归档时间: |
|
| 查看次数: |
24583 次 |
| 最近记录: |