Android:如何在运行时增加堆大小?

我在我的应用程序中使用SoftReferences实现了一个图像caching。 Dalvik以相对较小的启动应用程序,然后在需求的情况下增加它。 但是我想从一开始就让我的堆大一些。 这是因为,当我已经在caching中有一些图像,并且一个活动开始(例如)或其他高峰的内存需求发生,我的caching被清除,以便让内存的高峰需求。 因此,高峰消失后,我仍然有2-3 MB的可用空间,但我的caching是空的!

我看到这个麻烦的解决scheme是预先分配一个更大的堆正面,所以即使在2-3 MB的高峰消耗,它仍然有一些房间空间,所以我的SoftReferences不清除。

我发现VMRuntime.getRuntime().setMinimumHeapSize(BIGGER_SIZE)会有帮助。 特别是,谷歌在他们的应用程序中使用,如这里所述 。 但是, VMRuntime类被标记为废弃,并表示将在未来版本中从公共API中删除。 所以setMinimumHeapSize不是一个永久的解决scheme。

那么我怎么让Dalvik在启动的时候增长呢?

目前我使用一个非常简单直接的技巧,只需分配一个大arrays并释放它。 这使得Dalvik如我所愿地成长起来。 不过,我相信一定有更优雅的做法。 你能告诉我吗?

Related of "Android:如何在运行时增加堆大小?"

而不是增加堆大小,你可以做一些更好的事情。 正如你所说,你正在使用SoftReferences实现你的应用程序中的caching。 最好的事情是使用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中删除,并将新的图像加载到LruCache中。

如果caching比你说的要小,你可以自己决定一个有效的应用程序的脚印,并保持你自己的caching没有SoftReferences。

例如,通过一个简单的总字节计数器:只要添加或移动用于列表顶部的任何元素,如果它是新的,则将其大小添加到计数器。 如果总字节数超过了经验法则限制,则从底部删除,从而减less计数器。 也许LinkedHashMap类是有用的:它可以像HashMap一样用作caching,但是它也有一个像列表一样的顺序。

问题是,SoftReferences对在java堆空间中完成的分配非常有用,但图像是本地分配的,所以这种cachingtypes在Android上不会真正起作用。

您不能dynamic增加堆大小。

您可以通过在清单中使用android:largeHeap =“true”来请求更多的使用,但由于这只是一个请求,所以您可能不会获得比正常情况更多的堆大小。

另外,你可以使用本机内存,所以你实际上绕过了堆的大小限制。

这里是我已经提出的一些post:

  • 如何将位图caching到本机内存

  • JNI位图操作,帮助避免使用大图像时的OOM

这里是我为之制作的一个图书馆:

我不认为你可以或应该影响这个级别的设备的内存。 让系统做它的事情,不要反对它。 即使活动开始,您是否需要使用SoftReferences来保存这样一个大的图像caching?

您想检查它是如何在货架上完成的:请参阅http://code.google.com/p/shelves/source/browse/trunk/Shelves/src/org/curiouscreature/android/shelves/util/ImageUtilities中的第82行&#x7684;.java R = 26