2017-10-19 104 views
0

我正在通過this link from oracle並試圖瞭解/確認一些觀點。Java - 併發標記掃描中的標記/未標記對象GC

1)CMS階段 - 如果一個對象被標記爲「可達」,這也意味着該對象是活的?或者「Live」和「Reachable」不是「獨一無二」?

2)如果某些東西沒有標記爲「Reachable」,那麼默認情況下,Unreachable?或者簡單的原則「如果我沒有標記你爲Reachable,你無法接近」? 2)即使沒有明確提及,我假設在達到某個閾值(可能是某個時間戳或某個計數器)之後,所有舊一代(不標記爲「可達」)對象都被清除?

我必須說,這個鏈接是相當不錯的,但我想我是那些明確尋找「是/否」聲明的讀者之一。所以如果任何人都可以通過簡單的是/否來確認上面的問題,那麼它會做:)。

非常感謝。

回答

1

如果一個對象沒有被標記。這是「無法到達」

「無法到達」的對象還沒有死。它仍然存在於記憶中。但沒有任何對象可以參考它,因此沒用。在這種情況下,Dead的意思是「踢出舊世代空間」。

對於CMS GC,您必須使用JVM選項設置舊一代使用率閾值,它具有默認值。之後的內存使用量達到閾值,開始掃出「無法接通」的對象(現在是從內存中釋放)

+0

「無法到達的對象還沒有死」 - 我不確定這是正確的,因爲在該鏈接上它說「未標記對象==死對象」 – ha9u63ar

+0

@ ha9u63ar「死」有很多含義我想。我的話「死」意味着擺脫記憶。文檔的「死」比我的死更大意義 –

+0

如果我願意,我會對你的答案做一個小修改:) – ha9u63ar

0

什麼是俗稱的「活」,「不是垃圾」或「死」的一般正式的定義, 「垃圾」只考慮可達性

比較與The Java® Language Specification, §12.6.1. Implementing Finalization

每個對象都可以由兩個屬性來表徵的:它可以是可達終結可達的,或可達,並且它也可以是未確定可終結終定

A 可達對象是可以從任何活動線程進行任何潛在的持續計算中訪問的任何對象。

A 終結器可達可以從某個可終結對象通過一些引用鏈到達對象,但不能從任何活動線程到達對象。

一個無法達到無法通過任何方式達到目標。

安裝未終止對象從未自動調用終結器。

A 定稿對象自動調用了終結器。

A 可終結對象從來沒有自動調用終結器,但Java虛擬機最終可能會自動調用終結器。

所以¹,可達的意思是「活的」,可達手段「死」或「垃圾」和¹,不是可達意味着是可達和標記可達對象是測試不可達性的最直接方式。


¹只是因爲你說你喜歡的答案,在「是」或「否」


第三點不能用「是」或「否」的回答來看,因爲沒有「清潔」這樣的東西。

未終止對象被特殊列表引用。如果這些對象只能通過這個特殊的引用到達,他們將被列入終結,這使得它們可以終結。這些對象不是無法達到呢。

請注意,JVM優化了這一步,因爲大部分對象實際上並不需要完成。如果一個類從java.lang.Object繼承finalize()方法,或者有一個空的finalize()方法,則它被認爲是「平凡的終結器」,並且該類的實例首先不會被添加到未定義的對象列表中。這也適用於finalize()方法,該方法由唯一的super.finalize()呼叫到另一個平凡的終結器組成。

因此無法訪問對象是其終結器已被執行或具有「瑣碎終結器」的對象。在任何一種情況下,都不需要採取任何行動來「清除」它們。這些物體不像街道上的垃圾,必須拾取並放入垃圾箱。內存位置仍然包含對象處於活動狀態時所包含的內容,但未使用。實際上,在垃圾收集器檢測到它之前它已經沒有使用。

結束對象生命週期的關鍵是讓內存可用於新的分配。 CMS的掃描意味着通過內存並將不可達對象的地址添加到空閒內存列表。該階段直接在標記之後開始,但是如CMS中的C所示,同時

另一種方法是壓縮其中,其他仍然可到達的對象移動到不可訪問對象的位置。並且複製將移動(又名副本)全部可達對象到新的內存區域,使整個源區域可用於新的分配。

所有替代方案的共同之處在於,他們沒有對垃圾做任何事情來「清理」垃圾。即使是空閒內存的一部分,它們的內存仍然會包含之前的內容,直到被實際佔用並因此被另一個對象覆蓋。