3

在刪除一些大對象後,我正面臨着難以獲得更新的可用堆大小的應用程序。如何知道更新的可用堆大小?

我的要求是一旦用戶達到堆大小的特定級別,釋放內存。例如,我正在使用三星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()方法進入無限狀態,因爲它沒有得到更新的堆大小。

儘快給我一個解決方案。

回答

1

有幾個方面對這個問題:

1)你可能會使用Java管理豆獲得更可靠和詳細的統計數據,例如,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在必要時收集數據。

+0

感謝您的回答,但這是一個Android問題。 –

+0

是的,但我的答案仍然有效,即使對於Android。 – loonytune

2

Runtime.totalMemory()與調用時實際使用的堆的多少無關。它返回堆的實際大小。從documentation

返回堆的當前大小採取的字節數。

刪除對象不一定會改變堆大小。

你可以通過做得到堆的實際使用情況:

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

這就是說,也許你應該看看在android.util.LruCache或存儲東西你的圖片,而不是做這個管理自己。