我的应用程序中有一个使用SoftReferences实现的图像缓存。Dalvik使用相对较小的堆启动应用程序,然后在需要的情况下增加堆。但是我想从一开始就让我的堆更大一些。这是因为当我在缓存中已经有一些图像时,活动开始(例如)或发生其他峰值内存需求时,我的缓存将被清除,以便为该峰值需求释放内存。结果,在高峰过去后,我仍然有2-3MB的可用空间,但我的缓存是空的!
我看到的这个问题的解决方案是预先分配一个更大的堆,这样即使消耗了2-3MB的峰值,它仍然有一些空间,所以我的SoftReferences不会被清除。
我发现VMRuntime.getRuntime().setMinimumHeapSize(BIGGER_SIZE)会很有帮助。特别是,谷歌在他们的应用程序中使用了这一点,正如前面提到的here。但是,VMRuntime类被标记为已弃用,并且据说将在将来的版本中从公共API中删除。因此,setMinimumHeapSize不是一个永久性的解决方案。
如何让Dalvik在启动时增加我的堆?
目前,我使用的是一种非常简单和俗气的技术,只需分配一个大数组并释放它。这使得Dalvik可以按我所希望的那样增长堆。然而,我相信一定有更优雅的方式来做到这一点。你能告诉我吗?
发布于 2013-01-23 19:05:50
你可以做一些更好的事情,而不是增加堆大小。正如您所说的,您在使用SoftReferences实现的应用程序中维护缓存。最好的方法是使用LruCache,你可以这样做:
private LruCache<String, Bitmap> bitmapCache;
final int memClass;
int cacheSize;
memClass = ((ActivityManager) context.getSystemService(
Context.ACTIVITY_SERVICE)).getMemoryClass();返回当前设备的每个应用程序的大致内存类别。这让您知道应该对应用程序施加多大的内存限制,才能使整个系统工作得最好。返回值是以24为单位的;Android内存基准类别是16 (这恰好是这些设备的Java堆限制);一些内存更大的设备可能会返回24甚至更高的数字。
cacheSize = 1024 * 1024 * memClass / 10;
bitmapCache = new LruCache<String, Bitmap>(cacheSize) {
@Override
protected int sizeOf(String key, Bitmap value) {
return value.getHeight() * value.getRowBytes();
}
};如果内存超过LruCache的定位内存,它将从LruCache中删除位图图像,并将新图像加载到其中。
发布于 2011-04-25 04:30:43
如果缓存像你说的那样通常很小,你可以自己决定你的应用程序的有效占用空间,并在没有SoftReferences的情况下维护你自己的缓存。
例如,通过一个简单的总字节计数器:只需添加或移动列表顶部使用的任何元素,如果是新的,则将其大小添加到计数器。如果总字节数超过您的经验限制,则从底部删除,从而减少您的计数器。也许LinkedHashMap类对此很有用:它可以像HashMap一样用作缓存,但它的顺序也像list一样。
发布于 2011-02-24 03:36:38
问题是,SoftReferences对于java堆空间中的分配很有用,但图像是本地分配的,所以这种缓存类型在Android上不能真正工作。
https://stackoverflow.com/questions/4119405
复制相似问题