17

我正在编写一个图片库应用程序,但我一直遇到内存不足的错误。我缓存了所有图像,但是当我尝试在图像之间快速切换时会出现问题。我假设应用程序分配内存的速度快于 GC 释放它们的时间(因为当我缓慢切换图像时不会发生崩溃)。

经过几天的努力解决这个问题,我最终决定尝试在清单文件中设置 largeHeap。进行此设置后,无论我在图像之间切换多快,我的应用程序都不再崩溃。

现在,我想知道使用 largeHeap 设置是否有任何约定或一般准则,因为如果说笔记应用程序使用 largeHeap 可能没有多大意义。一般来说,哪些应用程序适合使用 largeHeap 设置?

谢谢

4

2 回答 2

23

一般来说,哪些应用程序适合使用 largeHeap 设置?

您可以向用户证明为什么要强制他们所有其他应用程序内存不足的原因,以便为您提供超大的堆空间。

就个人而言,我不会认为“图片库应用程序”有资格。AutoCAD、视频编辑器等都符合条件。

关于内存管理问题,请确保在 API 级别 11+ 上运行时使用inBitmapon BitmapOptions,以便回收现有缓冲区而不是进行垃圾收集。特别是对于图像库,您可能有很多相当一致的缩略图大小,回收现有缓冲区将是一个巨大的好处。这可以帮助整体内存消耗(即,你真的内存不足)和内存碎片(即,你得到一个OutOfMemoryError有足够的堆空间,但由于 Android 的 frakkin'非压缩,没有一个块足够大以供你分配垃圾收集器)。

您还可以考虑查看现有的图像缓存实现,例如Picasso的实现,看看是否有一些技巧可以学习(或者可能只是重复使用)。

于 2013-06-11T22:27:31.000 回答
2

首先,确保您没有加载比需要更大的位图:
Load a Scaled Down Version into Memory


然后,在尝试之前largeHeap,尝试自己快速释放内存

如果您bitmap.recycle();一确定就不会再使用位图,则立即调用,则该位图的大部分内存将立即被释放。(当 GC 处理它时,剩下的只是一个小对象。)


在较新的 Android 版本上,有recycle可能更有效的替代方法(而不是 ):
管理位图内存

就个人而言,我仍然经常使用,特别是如果我可能正在加载不同尺寸的图像,那么现有的recycle就不能。reuse此外,当更改为不同的片段或活动时,我发现将旧媒体的“卸载”与新媒体的“加载”分开编码更容易:
离开旧片段,所有旧位图 I recycle(然后,如果可以从静态字段,设置为null)。


是否使用 , 的经验法则是在您尝试了减少内存使用的替代方法largeHeap考虑它。

对您的应用程序进行编码,以便您可以再次将其关闭,并且仍然可以运行。

例如,监控您的内存使用情况,并在内存紧张时加载“按比例缩小”的位图。如果给定的图像不是他们设备的“视网膜”分辨率,用户真的会注意到吗?

或者,如果它是一个较旧、较慢的设备,largeHeap 是否会让您的应用程序感觉无响应/生涩?如果是这样,您能否进一步降低分辨率,或者一次显示更少的位图

让您的应用在任何情况下都能正常工作,而无需 largeHeap[通过上述技术]。注意:您可以通过分配一些“虚拟”位图来“强制测试”在紧张的内存上运行,并在全局字段中保存对它们的引用,这样它们就不会被释放。

现在您可以评估权衡,因为它会影响您的应用程序:

当您打开largeHeap时,请大量使用您的应用程序 - 是否现在它“更迟钝”,或者动画“口吃”或其他看起来不太流畅的地方?请务必在至少一台较旧的设备和一台 HIGH_RESOLUTION 设备上进行测试。由于堆较大,您可能会看到较长的 GC 时间。

或者,您可能会得出结论,这largeHeap对您来说效果很好,现在您可以自信地说它是您所处环境的最佳选择。

于 2017-02-28T21:45:29.263 回答