在删除一些大型对象后,我很难获得更新的应用程序堆大小。
我的要求是在用户达到特定的堆大小级别后释放内存。例如,我使用的是三星Tab3,它的堆大小为64 Mb。
应用程序在查看图像时不应该内存不足,因此我限制了55 MB作为堆大小增长的最大限制。我在查看图像之前检查可用的堆大小。如果堆大小超过55 MB,那么我删除了最近查看的一些图像,因此我可以获得足够的内存来加载图像。
但问题是,在删除图像对象后,我得到了最后一个增加的堆大小,总是大于55 MB。删除每个图像后我也调用了gc,但不影响。
我希望在删除图像对象后减小堆大小。
如果堆已达到55 MB,那么每个删除堆应该减少,如何减少堆大小?
我正在使用以下代码来获取可用的堆大小。
/**
* This method is used to get currently allocated heap size to application.
*/
public static int getAllocatedHeapSize()
{
DecimalFormat df = new DecimalFormat();
int size = new Double(Runtime.getRuntime().totalMemory()/1048576).intValue();
Log.d("heap", "debug.memory: allocated: " + size + "MB of " + df.format(new Double(Runtime.getRuntime().maxMemory()/1048576))+ "MB (" + df.format(new Double(Runtime.getRuntime().freeMemory()/1048576)) +"MB free)");
return size;
}
/**
* Check whether free memory is available to store new attachment page
* @return true if available else false
*/
public static boolean isFreeMemoryAvailable()
{
int allocatedHeapSize = getAllocatedHeapSize();
if (allocatedHeapSize > ) {
return false;
}
return true;
}
isFreeMemoryAvailable()方法是无限的,因为它没有获得更新的堆大小。
尽快给我一个解决方案。
答案 0 :(得分:2)
Runtime.totalMemory()
与调用时实际使用的堆的数量无关。它返回堆的实际大小。来自documentation:
返回堆以当前大小占用的字节数。
删除对象不一定会改变堆大小。
您可以通过执行以下操作来获取堆的实际用法:
Runtime.totalMemory() - Runtime.freeMemory();
也就是说,也许您应该考虑将图像存储在android.util.LruCache
或其他内容中,而不是自己进行管理。
答案 1 :(得分:1)
这个问题有几个方面:
1)您可以使用java管理bean获得更可靠和详细的统计信息,例如http://docs.oracle.com/javase/7/docs/api/java/lang/management/MemoryMXBean.html等(MemoryMXBean,MemoryPoolMXBean,GarbageCollectorMXBean)
2)你无法从java应用程序中减少堆大小,只能减少堆的使用量。
3)您可以考虑使用软参考http://docs.oracle.com/javase/7/docs/api/java/lang/ref/SoftReference.html。只要不需要空间,此类使您可以保留引用,并且仅在绝对必要时才收集它。这样,您可以限制堆大小,并使用软引用尽可能长时间地保留数据,但不要阻止GC在必要时收集它。