【问题标题】: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】:

      您可能没有足够的内存来创建大位图的旋转副本。

      您可以改为绘制原始图像的旋转图像。


      另外还有一些在处理图片时需要考虑的事情:

      • 始终加载缩放到 ImageView 大小的图像。
      • 始终回收您的图片
      • 如果仍有问题,请考虑使用 largeHeap=true。 Android 可能会过慢地增加堆大小(请参阅 https://stackoverflow.com/a/14462026/1390015)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-03-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-06-05
        • 1970-01-01
        • 2012-11-19
        • 1970-01-01
        相关资源
        最近更新 更多