java - 如何避免 Android 中的 OutOfMemoryError

标签 java android memory-management weak-references

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

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

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

有什么工作方法或想法吗?

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

<小时/>

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

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

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

最佳答案

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

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

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

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

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

关于java - 如何避免 Android 中的 OutOfMemoryError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23274495/

相关文章:

java - 如何获取外部可移动存储路径(micro SD卡)

android - 为什么 Delphi 10.3 应用程序在 Android 11 中崩溃?

c - *** 检测到 glibc *** : free(): invalid next size (fast) in C code

java - Spring Data Cassandra - 检索受影响的行

具有多个字段的 Java JTable 对象

java - 有没有办法限制Spring Batch的Job最大处理记录数?

c++ - 这怎么可能?字符串大小始终为 40 且结构大小为奇数读数

android - 有什么方法可以找出是什么阻止了我的应用程序的互联网访问?

java - 使用 Protobuf( Protocol Buffer )通过 Retrofit 进行 GET 和 POST 服务调用

ruby-on-rails - 有没有更有效的方法来存储商店的营业时间?