如何知道更新的可用堆大小?

时间:2015-06-22 09:17:12

标签: android memory-management garbage-collection heap-memory

在删除一些大型对象后,我很难获得更新的应用程序堆大小。

我的要求是在用户达到特定的堆大小级别后释放内存。例如,我使用的是三星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()方法是无限的,因为它没有获得更新的堆大小。

尽快给我一个解决方案。

2 个答案:

答案 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在必要时收集它。