Android位图处理-无泄漏但仍有OOM?

Android位图处理-无泄漏但仍有OOM?,android,memory-leaks,bitmap,Android,Memory Leaks,Bitmap,我正在编写一个照相机应用程序,当我拍摄一张照片时,我收到一个字节[],将其解码成位图并旋转,然后保存为JPEG。我使用本机库旋转照片,但是位图仍然从字节[]解码到内存中(仍然允许保留1个位图而不是2个)。因此,在我的代码中有一个地方,我需要大量的内存和OOM,在一些设备上,堆很低,摄像头是愚蠢的百万像素。有没有建议如何在不影响图像质量的情况下解决这个问题 我不想使用largeHeap=“true” 我应该忘记旋转而只设置EXIF吗 此外,我不太热衷于尝试“预测”我是否会OOM,因为数学没有加起来

我正在编写一个照相机应用程序,当我拍摄一张照片时,我收到一个字节[],将其解码成位图并旋转,然后保存为JPEG。我使用本机库旋转照片,但是位图仍然从字节[]解码到内存中(仍然允许保留1个位图而不是2个)。因此,在我的代码中有一个地方,我需要大量的内存和OOM,在一些设备上,堆很低,摄像头是愚蠢的百万像素。有没有建议如何在不影响图像质量的情况下解决这个问题

我不想使用
largeHeap=“true”
我应该忘记旋转而只设置EXIF吗

此外,我不太热衷于尝试“预测”我是否会OOM,因为数学没有加起来:

有没有建议如何在不影响图像质量的情况下解决这个问题

使用android:largeHeap=“true”

或者,使用其他一些本机库,它允许您将
字节[]
交给您,并为您进行旋转和保存到磁盘,以避免
位图和任何Java级别的处理

或者,如果
minSdkVersion
为19,并且其他逻辑支持它,请在
BitmapFactory.Options
上使用
inBitmap
,尝试重用已分配的
位图
对象,而不是分配新对象。此选项在早期版本的Android上可用,但对于那些版本,它必须在分辨率上完全匹配;在19+上,要重用的
位图
必须足够大,以处理要加载到其中的内容

我不想使用largeHeap=“true”

这可能没有帮助(并非所有设备都会提供更大的堆),而且更大的堆限制会给用户带来成本。这就是说,如果没有更多内存,操纵大型摄影机图像是很困难的,无论是在Java堆中还是表示来自本机代码的操作系统的分配

我应该忘记旋转而只设置EXIF吗

这当然是另一种可能性,尽管各种事情,如
ImageView
,似乎忽略了EXIF头

我不太热衷于尝试“预测”我是否会OOM,因为数学没有加起来


部分原因是Dalvik没有压缩/移动GC,而ART只有一个,而你的应用程序不在前台
OutOfMemoryError
表示没有单个连续的可用内存块可供您尝试分配。

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

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


此外,在处理图像时需要考虑以下事项:

  • 始终加载缩放到ImageView大小的图像
  • 始终回收您的图像
  • 如果仍然存在问题,请考虑使用largeHeap=true。Android的堆大小增长可能太慢(请参阅)