【发布时间】:2013-01-12 06:53:11
【问题描述】:
背景
Android 的最大堆大小非常有限,每个设备都有不同的最大堆。
某些应用需要能够在内存中缓存内容(通常是图像),而不仅仅是在内部/外部存储中。
当然,nice tips 很多关于处理位图和使用尽可能少的内存,但缓存也是必要的。
问题
我已经阅读了许多可能的缓存解决方案,但没有一个提供一种可以成为杀手级缓存解决方案的缓存。我想要的是具有以下功能的缓存机制:
无限使用堆,不用担心内存不足。应用程序需要内存并且没有足够的可用内存?所以释放一些(未引用的)项目(及其密钥)。
线程安全/并发。
提供基于 LRU 的缓存,以便最近使用的项目有更高的保留机会。
尽可能保持活力(但不会导致任何崩溃)。然而,遗憾的是,在 Android 上,与 Java 相比,软/弱引用的 GC 速度非常快。
能够处理隐藏其实际大小的对象。在 Android 上,在 API 10 及更低版本上,位图不使用堆内存,但被认为是这样的,因此 VM 无法知道何时释放它们,因为它认为使用与单个引用相同的内存量(4字节左右)。这就是为什么一些解决方案可以人为地判断每个项目的大小,以及何时需要移除它。
一些不错的可能解决方案
-
LruCache - API 12 中的一个类(不过,您可以轻松复制其代码)。
优势:#2 (?)、#3、#5。
缺点:#1、#4,加上你需要复制它的源代码,因为它是在 API 12 上呈现的。
-
其值具有软/弱引用的哈希图,如第 50 页上的here 所示,取自this lecture。
优点:#1(但不删除键),#2(需要使用ConcurrentHashMap)
缺点:#3、#4、#5
-
MapMaker(可从the guava library获得),类似于之前解决方案的高级版本。
优点:#1、#2
缺点:#3、#4、#5
Caching solutions 通过 guava 库。优点和缺点取决于您的选择。不确定哪种配置最适合需求,以及它是否在 Android 上运行良好。遗憾的是,我什至无法为 Android 编译库。
Android query - 不确定它是如何工作的。看起来很容易使用,但不确定它的优缺点。
问题
有人知道杀手级缓存机制吗?
我不太关心功能 #5,因为它非常先进,并且随着越来越多的人拥有更新的 Android 版本,将来不会那么需要。
【问题讨论】:
-
它是封闭的和过时的,但这是 android 性能的一个非常重要的方面,没有得到足够的讨论,特别是对于像位图这样的大对象。 Picasso 库对图像进行自动缓存,如果需要,您可以扩展它们的缓存大小。
标签: android caching bitmap out-of-memory heap-memory