LRU缓存:仅为整个应用初始化一个缓存?
在我的应用程序中,我有包含一些缩略图的不同列表视图。 今天我开始重构,我想实现LRU缓存。我遵循Android指南,但是我想知道是否最好只为整个应用初始化一个LRU缓存,或者更好地为每个列表视图初始化LRU缓存。 我害怕outOfMemory。 因此,我有以下问题,我不能自己回答: - 单个模式初始化一个LRU缓存是一个好主意? - 如果内存不足,是否会导致outOfMemory情况出现以下LRU Cache的初始化?LRU缓存:仅为整个应用初始化一个缓存?
@Override
protected void onCreate(Bundle savedInstanceState) {
...
// Get max available VM memory, exceeding this amount will throw an
// OutOfMemory exception. Stored in kilobytes as LruCache takes an
// int in its constructor.
final int maxMemory = (int) (Runtime.getRuntime().maxMemory()/1024);
// Use 1/8th of the available memory for this memory cache.
final int cacheSize = maxMemory/8;
mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
@Override
protected int sizeOf(String key, Bitmap bitmap) {
// The cache size will be measured in kilobytes rather than
// number of items.
return bitmap.getByteCount()/1024;
}
};
...
}
如果内存不足时,LRU缓存自动释放?我想知道当我使用LRU缓存(应用程序崩溃,因为内存不足)时应用程序是否会释放内存问题?
只有一个LRU缓存可用于整个应用程序吗?
- 整个应用程序有多个LRU缓存,它们会成为问题吗?
我有很多问题,所以我可以在这里给你一些有用的答案。
如果内存不足,LRU缓存会自动释放?我想知道如果,如果我用LRU缓存
的LRU缓存将不会自动释放内存的应用程序将有问题来释放内存。您需要以编程方式驱逐条目。
只有一个LRU缓存整个应用程序,它可以是一个问题?
整个应用程序有多个LRU缓存,它们会成为问题吗?
LruCache
类是一个泛型类,其中包含键的类型和值的类型。我想说你想要为每个要缓存的对象类型创建一个LRU缓存。你正在做我所做的事:缓存Bitmap
s和键入String
s。
只是旁注:小心使用bitmap.getByteCount()
。 JavaDocs说:
从KITKAT开始,此方法的结果不能再用于确定位图的内存使用情况。见
getAllocationByteCount()
。
我正在使用LRU Cache作为Bitmap
s。我认为只要调用此方法就可以覆盖Application.onTrimMemory()
并清除缓存。
此外,我做了同样的事情,并根据应用程序可用的堆内存的一定百分比设置缓存大小。
但在这里会发生什么:当我的应用程序在内存不足的状态,我的应用程序会尝试下载与内存不足的图像时,GC将运行,但BitmapFactory
仍然无法为Bitmap
分配内存。日志显示onTrimMemory()
方法异步调用,有时在投掷OutOfMemoryError
后几乎整整一秒!
HEY GOOGLE:如果系统不能告诉我,我的内存不足UNTIL OutOfMemoryError
被抛出后,如何在地狱我应该怎么管理我的记忆?
疯狂。纯粹,完全疯狂。
下面是我最终做的事情:我会在尝试块中捕获OutOfMemoryError
,清除那里的缓存,然后重试映像请求到服务器。他们告诉你不要做的确切事情。但它最终解决了我的问题。该应用现在更加稳定。
所以在你实现你的LRU缓存之后,确保你压力测试你的应用程序;尝试将其纳入低内存环境并查看其行为。对我来说,使用模拟器时效果最好。该模拟器将具有96M的小堆限制,但如果它具有高屏幕分辨率,则图像资源将会变得非常大,这使得内存最大化变得相当容易。
如果要显示缩略图,但你从服务器获取图像,他们可能比你的大ImageView
,请确保你阅读这篇文章:Loading Large Bitmaps Efficiently | Android Developers学习如何下载一个适当大小的位图,不浪费内存。
您也可以尝试让系统进行缓存并设置HttpResponseCache
。
无论你最终做什么,一定要强调你的应用程序,并看看它没有太多的堆剩余时的行为。
并准备处理一点挫败感。
嗨!此时我正在初始化listview构造函数中的weakHashMap,并将缩略图放在该地图中。我当时认为最好使用LRU缓存,但在阅读你的答案后,我有点害怕。 – aeroxr1
我刚才看了一下'WeakHashMap'。我没有意识到这是*键*在该类中具有弱引用,而不是值。出于这个原因,我想你可能想要像'Map>'这样的地图。我现在有点希望,我已经这样做了。由于'LruCache'类与GC没有任何隐含关系,因此几乎没有用处。所以你可能走在正确的轨道上。只要测试它的废话,如果它的行为可以接受,宣布胜利,并称它为一天。 –
在弱哈希图是弱关键的参考?真的吗?我不知道这个! – aeroxr1