寻找Android的"杀手"内存缓存机制

and*_*per 8 android caching bitmap heap-memory out-of-memory

背景

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. 具有用于它的值的软/弱引用的hashmap,如图此处第50页,取自本讲.

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

    缺点:#3,#4,#5

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

    优点:#1,#2

    缺点:#3,#4,#5

  4. 通过番石榴库缓存解决方案.优点和缺点取决于您的选择.不确定哪种配置最符合需求,以及它是否适用于Android.遗憾的是,即使为Android编译库也无法成功.

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

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

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

all*_*rog 2

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

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