8

背景

Android 的最大堆大小非常有限,每个设备都有不同的最大堆。

一些应用程序需要能够在内存中缓存内容(通常是图像),而不仅仅是在内部/外部存储中。

当然,有很多关于处理位图和使用尽可能少的内存的好技巧,但缓存也是必需的。

问题

我已经阅读了许多可能的缓存解决方案,但没有一个提供一种可以成为杀手级缓存解决方案的缓存。我想要的是一种具有以下功能的缓存机制:

  1. 无限使用堆,不用担心内存不足。应用程序需要内存并且没有足够的可用内存?所以释放一些(未引用的)项目(及其密钥)。

  2. 线程安全/并发。

  3. 提供基于 LRU 的缓存,以便最近使用的项目有更高的保留机会。

  4. 尽可能保持活力(但不会导致任何崩溃)。然而,遗憾的是,在 Android 上,与 Java 相比,软/弱引用的 GC 速度非常快。

  5. 能够处理隐藏其真实大小的对象。在 Android 上,在 API 10 及更低版本上,位图不使用堆内存,但被认为是这样的,因此 VM 无法知道何时释放它们,因为它认为使用与单个引用相同的内存量(4字节左右)。这就是为什么一些解决方案可以人为地告诉每个项目的大小,以及何时删除它。

一些好的可能解决方案

  1. LruCache - API 12 中的一个类(尽管您可以轻松复制它的代码)。

    优点:#2(?),#3,#5。

    缺点:#1、#4,加上你需要复制它的源代码,因为它是在 API 12 上呈现的。

  2. 一个哈希图,其值具有软/弱引用,如第 50 页所示取自本讲座

    优点:#1(但不删除键),#2(需要使用ConcurrentHashMap

    缺点:#3、#4、#5

  3. MapMaker(可从guava 库中获得),类似于之前解决方案的高级版本。

    优点:#1、#2

    缺点:#3、#4、#5

  4. 通过 guava 库缓存解决方案。优点和缺点取决于您的选择。不确定哪种配置最适合需求,以及它是否在 Android 上运行良好。可悲的是,我什至无法为 Android 编译库。

  5. Android 查询- 不确定它是如何工作的。看起来很容易使用,但不确定它的优缺点。

问题

有人知道杀手缓存机制吗?

我不太关心功能 #5,因为它非常先进,并且随着越来越多的人拥有更新的 Android 版本,将来不会那么需要。

4

3 回答 3

2

正如我所看到的,#1 存在一个实际的禁止问题。您不能释放从应用程序的其他部分引用的对象;因此,不可能创建一个随意释放内存的构造。

我看到的唯一解决方案是创建自己的支持 LRU 并且能够处理弱引用和强引用的缓存。一个项目开始是一个强引用的东西,如果有一段时间不使用,或者强制执行内存限制,你可以将其更改为弱引用。这并不容易创建,并且必须确保在所有应用程序中进行微调。

于 2013-01-28T20:41:24.560 回答
0

看看 Android BitMap Cache,它是 LruCache 的一个大大改进的版本。

http://www.senab.co.uk/2013/01/24/android-bitmapcache-v2-1/

于 2013-01-28T21:15:43.560 回答
0

您可能正在寻找更通用的解决方案,但如果您主要关注图像,请查看ImageLoader。我已经使用了一段时间,它非常适合我需要的东西。初始化它时,您可以告诉它使用 LRUCache 并告诉它要使用的可用内存百分比。

附带说明一下,HttpResponseCache使得缓存来自服务器的数据非常非常好。

于 2013-01-28T21:02:22.330 回答