gpt4 book ai didi

android - 软引用在 Android 上的行为不符合预期

转载 作者:行者123 更新时间:2023-11-29 15:10:59 25 4
gpt4 key购买 nike

我在Android上使用软引用的时候遇到了一个奇怪的问题。我实现了一个位图缓存的类,源码如下:

public class ImageCache
{
private static HashMap<String, SoftReference<Bitmap>> mCache = new HashMap<String, SoftReference<Bitmap>>();
private static final String TAG = "ImageCache";
public static Bitmap getBitmap(String url)
{
Bitmap bitmap = null;
if (mCache.containsKey(url))
{
Log.d(TAG, "use cache: " + url);
bitmap = mCache.get(url).get();
if (bitmap != null)
{
return bitmap;
}
else
{
Log.w(TAG, "#######################soft ref was collected!!!");
}
}
bitmap = BitmapFactory.decodeFile(url);

if (bitmap == null)
{
Log.e(TAG, "#####jpg not found");
return null;
}
bitmap = Bitmap.createScaledBitmap(bitmap, 320, 240, false);
synchronized (mCache) {
mCache.put(url, new SoftReference<Bitmap>(bitmap));
}
return bitmap;
}
}

但是我通过logcat发现软引用被频繁收集。日志是:

#######################soft ref was collected!!!

据我所知,只有当 java 堆增长到极限并且没有空间分配新的内存时,GC 才会收集软引用。

但为什么软引用在 Android 上的表现不如预期?

最佳答案

As far as I know, soft reference will be collected by GC only if java heap grow to its limit and there is no space for a new memory allocation.

这是不正确的。

根据 Oracle documentation , 如果 GC 决定这样做,任何给定的 SoftReference 都可以随时收集。甚至还有 VM 参数,称为 -XX:SoftRefLRUPolicyMSPerMB。所以 SoftReferences 意味着在不得不增加堆大小之前被清除,即使在桌面 JVM 上也是如此(另请参阅 this question 以了解有关该问题的一些额外详细信息)。

安卓documentation提供更少的保证,并且 clearly warns ,虚拟机实际上不会坚持长时间保留这些引用:

Unlike a WeakReference, a SoftReference will not be cleared and enqueued until the runtime must reclaim memory to satisfy an allocation.

我个人将其解读为“直到下一个 GC_FOR_ALLOC”。

SoftReferences 肯定有一些有效的用途,例如使它们成为 circuit breaker .链接的文章还解释了为什么缓存不是其中之一。如果您想以某种方式管理您的缓存,这实际上很重要,请使用内存受限的 LruCache 并从 onLowMemory() 中清除它。或者,更好的是,在使用位图后放开它们,让操作系统决定缓存什么以及何时销毁您的应用程序及其缓存。

关于android - 软引用在 Android 上的行为不符合预期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31509201/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com