【问题标题】:Android bitmap processing - no leak but still OOM?Android 位图处理 - 没有泄漏但仍然 OOM?
【发布时间】:2015-07-27 10:22:30
【问题描述】:
我正在编写一个相机应用程序,当我拍照时,我收到一个字节 [],将其解码为位图并在将其保存为 JPEG 之前对其进行旋转。我正在使用本机库旋转照片,但是为此,位图仍然从 byte[] 解码到内存中(仍然允许我保留 1 个位图而不是 2 个)。所以基本上在我的代码中有一个地方我需要大量内存和 OOM 在一些堆低并且相机是愚蠢的百万像素的设备上。有什么建议可以在不降低图像质量的情况下解决这个问题吗?
我想我不想使用largeHeap="true"
我应该忘记轮换而只设置 EXIF 吗?
此外,我不太热衷于尝试“预测”我是否会 OOM,因为数学没有加起来:Android OutOfMemory when GC reports free memory?
【问题讨论】:
标签:
android
memory-leaks
bitmap
【解决方案1】:
有什么建议可以在不损失图像质量的情况下解决这个问题吗?
使用android:largeHeap="true"。
或者,使用其他本机库,允许您移交 byte[] 并为您执行旋转和保存到磁盘,以避免 Bitmap 和任何 Java 级别的大型处理。
或者,如果您的 minSdkVersion 是 19,并且您的其余逻辑支持它,请在 BitmapFactory.Options 上使用 inBitmap 以尝试重用已分配的 Bitmap 对象,而不是分配新的对象。此选项在早期版本的 Android 上可用,但对于那些必须在分辨率方面完全匹配;在 19+ 上,要重复使用的 Bitmap 必须足够大,以处理您尝试加载的内容。
我不认为我想使用 largeHeap="true"
这可能无济于事(并非所有设备都会为您提供更大的堆),并且用户会因更大的堆限制而付出代价。话虽如此,如果没有更多内存,无论是在 Java 堆中还是表示来自本机代码的操作系统分配,如果没有更多内存,操作大相机图像是很困难的。
我应该忘记旋转并只设置 EXIF 吗?
这当然是另一种可能性,尽管 ImageView 等各种东西似乎都忽略了 EXIF 标头。
我不太热衷于尝试“预测”我是否会 OOM,因为数学没有加起来
部分原因是因为 Dalvik 没有压缩/移动 GC,而 ART 只有一个,而您的应用程序不在前台。 OutOfMemoryError 表示您尝试分配的内存没有单个连续的空闲内存块。
【解决方案2】:
您可能没有足够的内存来创建大位图的旋转副本。
您可以改为绘制原始图像的旋转图像。
另外还有一些在处理图片时需要考虑的事情: