2012-02-22 47 views
1

我很好奇,在Java中是否有任何方法可以根據需要釋放內存 - 就像iOS中的UIApplicationDidReceiveMemoryWarningNotification一樣?例如,我可能在我的程序中有一個用作緩存結構的數組,當JVM有內存壓力(堆空間正在耗盡)時,我可以通過強制GC和清理數組緩存?Java內存管理:iOS風格內存監控?

,如果你認爲這個問題不明確你〜

回答

3

GC在需要時自動運行,所以您不需要通知。

對於要手動刪除條目時內存不足緩存,您可以使用SoftReference秒。如果您僅保留對緩存項的軟引用,則垃圾收集器將自動從緩存中刪除條目,如果它需要更多內存。

已經有相當多的緩存實現爲您處理這個問題(例如在Guava庫(參見CacheBuilder))。

+1

+1只是想發佈一個類似的答案與softreferences和番石榴:)更好地瞭解java引用我發現[這篇文章](http://www.kdgregory.com/index.php?page=java.refobj)有用。 – 2012-02-22 14:13:22

+0

感謝您的回答!很高興看到這是一個很好的答案(@PhilippWendler @ortang和@mikera)! – asksw0rder 2012-02-22 16:48:20

0

的Java虛擬機本身管理的過程中,請發表評論。 您只需對您的緩存對象進行空引用,然後調用 System.gc()

然後,Java將清理堆空間。據我所知,你無能爲力。

+2

調用System.gc()不會調用垃圾回收器。相反,它給了虛擬機一個暗示它可以這樣做的暗示。它是否真的選擇這樣做。一般來說,調用System.gc()不是解決問題或任何問題的答案。老實說,我從來沒有見過這樣的情況,稱它爲實際有用(儘管我很樂意看到它)。 – RHSeeger 2012-02-22 14:35:25

2

在Java中,您通常應該讓GC爲您處理內存。

如果您想要在存在內存壓力時清除緩存,那麼您應該使用基於軟引用(這是Weak References更一般類別的變體)的緩存。如果一個對象僅被軟引用引用,那麼GC將在內存不足之前將其清除。

創建軟參考緩存的簡單方法是使用Guava的CacheBuilder

1

除了已經提到的SoftReference,你可以簡單地註冊一個通知,觸發例如在大約95%的內存使用情況下:

MemoryMXBean mbean = ManagementFactory.getMemoryMXBean(); 
NotificationBroadcaster emitter = (NotificationBroadcaster) mbean; 
emitter.addNotificationListener(new NotificationListener() { 
    public void handleNotification(Notification notification, Object handback) { 
    System.out.println("Low memory notification"); 
} 
}, null, null); 
for (MemoryPoolMXBean memPool : ManagementFactory.getMemoryPoolMXBeans()) { 
    if (memPool.isUsageThresholdSupported()) { 
    MemoryUsage memUsage = memPool.getUsage(); 
    memPool.setUsageThreshold((long) (memUsage.getMax() * 0.95)); 
    } 
} 
+0

感謝@羅伯特的答案!我想我會先嚐試番石榴,但這絕對是一種方式。 – asksw0rder 2012-02-22 16:50:28