2011-03-16 69 views
10

是否有可以標記java中的對象以便在下次清理時進行垃圾回收?標記要刪除的對象在GC中

我聽說將對象設置爲null不再有效。

+2

你能否提供關於爲什麼設置對象爲'null'是行不通的一些鏈接或文件?當然,設置爲'null'也不能保證它會被刪除。 – 2011-03-16 20:41:06

+1

只要您消除對某個對象的所有引用(例如,通過設置對「null」的引用),它就會成爲垃圾收集的*符合條件*。在回收內存之前,您不會耗盡內存(假設它會導致堆空間不足和堆耗盡)。實際發生的GC取決於虛擬機。它爲什麼關心你? – 2011-03-16 20:49:16

+2

它是一個問題,因爲我正在處理大量包含相當數量數據的對象。一次分配通常在1000年以後。 – monksy 2011-03-16 20:54:09

回答

4

我知道這個問題已經得到解答,但您可以通過多種方式操縱Java垃圾收集器查看您的引用的方式。您可以通過軟參考,弱參考和幻影參考來做到這一點。查看java.lang.ref包以獲得更好的解釋。

http://download.oracle.com/javase/1.5.0/docs/api/java/lang/ref/package-summary.html

而且,這裏是一個很好的樣本,以確定何時幻影即將進行垃圾回收。

http://exampledepot.8waytrips.com/egs/java.lang.ref/PhantomRef.html

下面是它來自主網站:

http://exampledepot.8waytrips.com/

+0

這就是我尋找的信息種類 – monksy 2011-03-17 00:04:51

+0

這也是有趣的:http: //weblogs.java.net/blog/2006/05/04/understanding-weak-references – monksy 2011-03-17 14:36:49

2

Java垃圾收集器使用標記和清除方法。這意味着從已知仍在使用的對象開始,遵循所有引用,並且以這種方式訪問​​的對象被標記。那樣沒有引用的對象就沒有標記,並且一定要刪除。因此,您可以確保刪除對該對象的所有引用,以便在垃圾收集器的下一輪中刪除該項目。

此外,您可以使用

Runtime.getRuntime().gc(); 

,表明垃圾收集器應該運行。注意:你不能確定它確實運行。

+0

垃圾收集器不基於引用計數。所有現代的JVM都是標記式的,其中大部分是多代的。 – 2011-03-16 20:45:27

+0

它不依賴於JVM的實現嗎? – RoflcoptrException 2011-03-16 20:46:08

+0

編號引用計數不允許您正確實現Java語言規範,因爲引用循環存在問題。因此,不僅沒有現有的JVM實現使用引用計數,沒有實現完全不同且正確的收集機制的情況下,沒有任何可以遵從。 – 2011-03-16 20:47:24

7

不,你不能。如果另一個變量引用了它,你會期望發生什麼?

請注意,您不能將對象設置爲空 - 您只能將變量設置爲空。如果另一個變量仍然有對象的引用,它仍然不符合垃圾回收的條件。

如果您認爲您需要這樣做,那可能意味着您誤解了您的數據 - 或者您的代碼中可能存在泄漏(例如,您只添加條目的列表,由靜態引用變量 - 當類加載器處於活動狀態時,這些條目永遠不會有資格進行垃圾回收)。每個JVM都有自己的GC,但在Hotspot中,當GC運行於當前「生活」對象的生成時(假設它沒有終結器,這會使事情複雜化),對象將被垃圾收集。如果物體處於「年輕」一代,那麼很可能會很快發生 - 如果它處於「老」一代,它可能需要更長的時間。

您可能希望看到Java 6 GC tuning documentation更多的信息,當然,事情後來又跳槽然後OpenJDK 7的等

+0

正如我在評論中所說,我創造了很多很多的對象,並且在完成處理之後,我不再需要它們了。我懷疑[由探查者支持]他們沒有受到任何損害。 – monksy 2011-03-16 20:56:18

+0

@monksy:然後,這表明你已經有了一個潛伏在某處的引用,假設GC正在運行。 – 2011-03-16 21:01:24

+1

這就是我的懷疑[目前啓動的對象數量很少會減少,它不斷增長]有沒有什麼工具可以幫助你呢?我不得不使用Netbeans Profiler來發現這一點。 – monksy 2011-03-17 00:04:01

1

你沒聽錯,但隨後又描述是錯誤的了。

您不要將對象設置爲null,您將變量設置爲null。如果變量可以用於獲取對象,則該變量具有對該對象的「引用」。將變量設置爲null與變量「丟失對象的引用」相同。

一旦Java檢測到一個對象或一組對象無法通過正在運行的程序到達,它將從內存中刪除這些對象。它不會在一瞬間將它們從內存中移除,因爲如果它確實存在,並且程序的某些其他部分試圖使用對該對象的引用,那麼該引用將以Java中不允許的方式失敗。

訣竅不是隻設置一個引用爲null,而是必須將所有可能已經設置爲null的引用。這就是爲什麼每次創建新引用時都要考慮這一點,因爲您希望以最終被清除的方式創建它們(除非需要內存泄漏)。