【问题标题】:How to know updated available heap size?如何知道更新的可用堆大小?
【发布时间】:2015-09-07 16:24:08
【问题描述】:

在删除一些大对象后,我在更新应用程序的可用堆大小时遇到​​了困难。

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

尽快给我解决方案。

【问题讨论】:

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


    【解决方案1】:

    Runtime.totalMemory() 与调用时实际使用的堆大小无关。它返回堆的实际大小。来自documentation

    返回堆以当前大小占用的字节数。

    移除对象并不一定会改变堆大小。

    您可以通过以下方式获得堆的实际使用情况:

    Runtime.totalMemory() - Runtime.freeMemory();
    

    也就是说,也许您应该考虑将图像存储在 android.util.LruCache 或其他东西中,而不是自己进行这种管理。

    【讨论】:

      【解决方案2】:

      这个问题有几个方面:

      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 收集数据。

      【讨论】:

      • 感谢您的回答,但这是一个 android 问题。
      • 是的,但我的回答仍然有效,即使对于 android 也是如此。
      猜你喜欢
      • 2019-09-17
      • 2019-08-25
      • 1970-01-01
      • 2019-03-19
      • 1970-01-01
      • 2015-08-09
      • 2015-08-07
      • 2019-07-27
      相关资源
      最近更新 更多