【问题标题】:How to avoid OutOfMemoryError in Android如何避免 Android 中的 OutOfMemoryError
【发布时间】:2014-04-24 16:21:19
【问题描述】:

我正在开发一个需要在内存中存储许多位图图像的应用程序。毫不奇怪,当位图集合变得太大时,OutOfMemoryError 经常在某些设备上被捕获。我需要以某种方式避免这种情况。

简单地说,我需要一种集合,它会表现出一种“逐个添加项目,直到添加下一个项目会导致OutOfMemoryError”,但我没有足够的经验找到一个适当的方法。我相信,应该实现某种弱引用集合。

我喜欢WeakHashMap,但它有一个关键问题——我无法控制如何丢弃物品。在我的应用程序中,位图是按优先级顺序添加的:最重要的位图,应该尽可能长时间地存储,首先放置。据我了解,WeakHashMap 没有提供这样的优先级。

有什么可行的方法或想法吗?

P. S. 这个问题不是关于位图优化的。想象一下,有一些无法压缩或优化的大对象而不是位图。问题是关于将项目存储在内存中直接控制它们的优先级,以便可以快速 GC 或根本不添加低优先级的对象


P。 P.S. 到目前为止,我发现了两种可能的解决方案:

1) 将集合分为两部分,第一,优先级更高,将包含项目本身(即强引用),第二部分将包含软引用。可以使用Runtime.getRuntime.maxMemory().totalMemory() 处理添加控制--当堆占用的totalMemory 超过maxMemory 的某个百分比时,应禁止将新项添加到集合中;

2) 使用软引用的集合并跟踪项目的finalize()--当它被调用时(即相应的对象将被 GC 拾取),将此项目作为软引用返回到集合并替换另一个项目 - 具有最低优先级 - 通过幻像引用。从理论上讲,这会提供更严格的优先级控制,但我不确定它在实践中会如何表现。

【问题讨论】:

标签: java android memory-management weak-references


【解决方案1】:

LruCache 类似乎是一个很好的候选对象。

http://developer.android.com/reference/android/util/LruCache.html

保存对有限数量值的强引用的缓存。每次访问一个值时,它都会移动到队列的头部。当一个值被添加到一个完整的缓存中时,该队列末尾的值将被逐出并可能成为垃圾回收的条件。

这似乎提供了您想要的生命周期控制。此外,缓存大小由您控制,因此您可以动态创建使用可用内存百分比的缓存,即自动调整可用内存量。

http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html 上的相关文章给出了它的使用示例,包括用于未存储在 RAM 中的对象的后备磁盘缓存。

【讨论】:

  • 如果可以直接控制优先级,而不是通过调用项目...
  • 深入了解 LruCache 源代码以更好地了解它是如何做到这一点的,看来基础是正确的,您可以推出自己的 LruCache 实现
  • 我想我将不得不...我想问我的问题时有一些标准的解决方案
  • csmith 不幸的是,android 的 LruCache 只是一个普通的固定大小的 LRU 缓存实现。那里没有实现 GC 控制...在我们不确定对象的大致大小的情况下是无能为力的。
猜你喜欢
  • 1970-01-01
  • 2017-03-20
  • 2013-06-05
  • 2018-01-11
  • 1970-01-01
  • 2011-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多