2014-09-03 62 views
0

我對Java很陌生,我想知道不同版本的HotSpot JVM垃圾收集器的結構和垃圾收集過程的原理(我主要感興趣的是Java 1.6中使用的,1.7和1.8),但不幸的是,我無法在Java中找到涵蓋此主題的廣泛資源。熱點JVM垃圾收集器

  1. 你能不能給我推薦一些參考,我可以閱讀更多關於不同版本的HotSpot JVM垃圾收集器的?

  2. 永久生成段是JVM堆的一部分嗎? 甲骨文OBE教程說,它是: 「堆部分是:年輕一代,老,年老代和永久代」 (Source) 但是馬克尼爾森談到永久代和堆分開(Source)。

  3. 這是真的,字符串文字存儲在堆中,但不是從1.7 Java版本開始的永久代? (Source

  4. 在JVM中的哪些是存儲的基元?它是一堆還是永久的一代?

  5. JVM中的常量是存儲的嗎?它是一堆還是永久的一代?
+0

您好!我對我的帖子進行了更改,請檢查它並保留。我認爲現在它更孤立。 – invaa 2014-09-03 17:55:56

回答

0

Java中有多個垃圾收集器;但流行的研究是「伊甸園」和老化模型。

當然,現在大多數人都在運行G1垃圾回收器,即使那個流行的模型通常也沒有描述真正發生的事情。不要太擔心這種不準確的情況,因爲有不少發佈,這是事實上的默認。

垃圾收集是關於兩個主要任務,回收記憶和孔壓實。

  1. 回收記憶首先在概念上完成。如果JVM無法從非死的線程到達對象,則對象將被回收(因爲它不能成爲將來執行的程序的一部分......對象的句柄/地址的知識已被永久丟失) 。
  2. 一旦對象被回收,它們將堆放在「瑞士奶酪」狀態,其中一些區域正在使用,其他區域爲空(由於回收)。壓縮嘗試去除堆中的「漏洞」,試圖分配大對象的操作不會失敗,因爲所請求的內存不可用作連續的一系列地址。

隨着老伊甸園式的垃圾收集器的想法是

  1. 新創建的對象是在被開墾,因爲他們很可能是塊(的範圍內產生高風險和引用會退出該塊時可能會丟失)。
  2. 欠新創建的對象是在被收回,因爲它們存活它們在被創建的塊風險更低。

這樣,將「Eden」的空間是其中對象WASN」堆的一部分但仍檢查JVM程序執行線程是否仍然可以訪問它。倖存者空間是對象被複制到的位置(複製允許重新設置地址並因此壓縮),而其他更永久的空間表示更長壽命的對象。

現在使用新的G1垃圾回收器,您實際上擁有數千(至數百萬)的小堆,並且整個堆基於其包含的對象的生存能力進行標記。有時通過組合兩個「堆塊」來完成壓縮;然而,由於堆非常小,通常它們只是被丟棄而不是壓縮(由於在需要考慮更少的對象時堆中的所有對象都無法訪問)的可能性更大。

+0

請注意,在少於一半的堆使用情況下,通常它們的默認算法是「複製和掃描」,這大致意味着,當我檢測到正在使用的對象時,我將它複製到另一半的內存中,並在完成時檢測,我掃過舊的一半乾淨。這個過程重複進入席捲的一面。它具有一些獨特的性能優勢(儘管是複製),因爲它在壓實方法上很簡單。 – 2014-09-03 08:10:27

+0

非常感謝。但是,你能告訴我,所有的常量和字符串文字都存儲在JVM中嗎?說燙髮是JVM堆的一部分是正確的嗎? – invaa 2014-09-03 12:27:05

+0

大多數真正的文字最初是在'.class'文件的常量池中定義的。燙髮根本不是堆的一部分,因爲燙髮一旦進入燙髮階段,它就不能真正被回收。然而,在Java 8中,存儲在perm gen中的東西現在存儲在堆中(理論上可以回收,除了到達永久生成時,它不清楚它何時(如果有的話)適合於回收它)。如果JVM決定解壓類並將所有常量內部化到一箇中央位置,那麼這是JVM的實現細節,而不是要求。 – 2014-09-03 15:00:21