我的应用程序中有一个图像缓存,该图像缓存是使用SoftReferences实现的。 Dalvik以相对较小的堆启动应用程序,然后在有需求的情况下增加堆。但我想从一开始就增加堆大小。那是因为当我在缓存中已经有一些图像并且开始 Activity (例如)或发生其他峰值内存需求时,会清除我的缓存以让内存满足该峰值需求。结果,在峰值消失之后,我仍然有2-3 MB的可用空间,但是我的缓存为空!
我看到的解决此问题的方法是预先分配一个更大的正手堆,因此即使峰值消耗为2-3 MB,它仍然具有一定的空间,因此不会清除我的SoftReferences。
我发现VMRuntime.getRuntime().setMinimumHeapSize(BIGGER_SIZE)
会有所帮助。如here所述,Google特别在其应用程序中使用了它。但是,VMRuntime类被标记为已弃用,并表示在将来的版本中将从公共(public)API中删除。因此,setMinimumHeapSize
不是永久性的解决方案。
然后如何让Dalvik在启动时增加堆大小?
目前,我通过分配一个大数组并释放它来使用一种非常简单明了的技术。这使Dalvik可以根据需要扩展堆。但是,我敢肯定,必须有更优雅的方法来做到这一点。你能告诉我吗?
最佳答案
除了增加堆大小,您还可以做一些更好的事情。如您所说,您正在维护使用SoftReferences实现的应用程序中的缓存。最好的办法是使用LruCache,您可以执行以下操作:
private LruCache<String, Bitmap> bitmapCache;
final int memClass;
int cacheSize;
memClass = ((ActivityManager) context.getSystemService(
Context.ACTIVITY_SERVICE)).getMemoryClass();
返回当前设备的近似每个应用程序的内存类。这样可以使您了解应该对应用程序施加多大的内存限制,以使整个系统发挥最佳作用。返回的值以兆字节为单位;基线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中删除位图图像,并在其中加载新图像。