Android:位图、软引用和书籍?

Posted

技术标签:

【中文标题】Android:位图、软引用和书籍?【英文标题】:Android: Bitmaps, SoftReferences, and OOMs? 【发布时间】:2011-05-19 20:16:44 【问题描述】:

我在垂直线性布局中有一系列视图。每个视图在滚动到时都会生成并绘制一个位图。出于性能原因,我宁愿在每次调用 onDraw() 时都不生成位图,但出于内存原因,我不能保留对位图的硬引用。我可以就我应该采取的策略提出建议。

我已经尝试了明显的方法:生成位图,然后用 SoftReference 包装它。这失败了有两个原因。 1. 参考文献的收集比我预期的要热切得多。 2. 我仍然得到 OOM!这令人震惊,因为没有 Bitmap 是特别大的,所以单个视图不应该导致 OOM,让我假设 OOM 的发生是因为有问题的 SoftReference(s) 没有被释放的机会。此外,当我的应用程序分配的堆大小为 6mb(根据 DDMS 视图)时,会发生 OOM,我预计它会在抛出 OOM 之前增长到 16mb。

有什么建议吗?

【问题讨论】:

注册。 “分配的堆大小为 6mb(根据 DDMS 视图)”:阅读我的回复:***.com/questions/3238388/… ... 6 mb 不是位图占用的分配大小。位图占用本机堆。 谢谢您,我尝试了您帖子中推荐的日志记录策略。这确实解释了为什么它在“6 mb”时出现 OOM。根据您的日志记录代码,当我的本机使用量达到 12mb(而我的应用程序使用量约为 4mb)时,它会 OOM。这是有道理的,因为这是 16mb 的使用量。但是,如果我的位图在 SoftReferences 中,它们不应该在达到 12mb 时被收集吗??? 软引用与内存使用无关。 我的理解是,如果需要内存,将对象包装在 SoftReference 中将指示垃圾收集器释放该对象。并且垃圾收集器在抛出 OOM 异常之前运行。因此,如果对象在 SoftReference 中,则不应导致 OOM,因为如果需要内存,则应释放该对象。 【参考方案1】:

问题在于位图使用终结器,因此,在实际释放本机内存之前,可能需要经过几次 GC。这是我们正在努力改进的东西。

【讨论】:

在此期间您有什么建议吗?我想我应该这样做:保持位图的某种全局跟踪,如果位图的总大小开始变得危险,则开始手动释放它们?有什么建议可以让这样的解决方案不那么随意吗? 您应该在最近最少使用的位图上手动调用 recycle()。 我假设 recycle() 会将其标记为未使用,然后在下次垃圾收集器运行时将其清理?如果是这样,这与使用 SoftReference 有何不同? 我目前也有这个问题。与等待 GC 为您清理它相比,回收位图会立即释放内存。 developer.android.com/reference/android/graphics/… 不幸的是,当我回收时,我最终得到了一个异常,说我试图使用回收的位图。 Romain,在 ShopSavvy,我们正在我们的产品屏幕上创建一个大位图来显示产品图像。当屏幕被破坏时,我在每个位图上手动调用回收,但是本机堆似乎永远不会变小。它只会不断增长,直到最终手机出现 OOM(有些手机比其他手机快)。你有什么建议可以给吗?我确保在每个位图上都调用了回收,并且随后也调用了 finalize 方法,该方法应该删除本机堆上的指针。

以上是关于Android:位图、软引用和书籍?的主要内容,如果未能解决你的问题,请参考以下文章

Android性能提升之强引用软引用弱引用虚引用使用

Android性能优化之巧用软引用与弱引用优化内存使用

Android内存调优的一些方法

Android 内存泄漏

Android软引用(SoftReference)与LruCache

聊聊JVM软引用和弱引用