說到垃圾回收(Garbage Collection,GC),很多人就會(huì)自然而然地把它和Java聯(lián)系起來(lái)。在Java中,程序員不需要去關(guān)心內(nèi)存動(dòng)態(tài)分配和垃圾回收的問題,這一切都交給了JVM來(lái)處理。
1.為什么Java中需要垃圾收集?
在許多編程語(yǔ)言中,如C和C++,當(dāng)程序不再需要對(duì)象時(shí),開發(fā)人員必須采取編程步驟來(lái)回收對(duì)象在內(nèi)存中分配的任何空間。
如果實(shí)施得當(dāng),這種方法可能會(huì)非常有效。然而,歷史已經(jīng)表明,當(dāng)這個(gè)過程做得不好時(shí),可能會(huì)發(fā)生內(nèi)存泄漏并導(dǎo)致應(yīng)用程序崩潰。
當(dāng)Java語(yǔ)言被創(chuàng)建時(shí),Sun工程師決定開發(fā)人員不應(yīng)該負(fù)責(zé)管理他們創(chuàng)建的對(duì)象所使用的內(nèi)存。相反,垃圾收集例程將是JVM的一部分;此例程識(shí)別不再使用的對(duì)象,并將其從內(nèi)存中刪除。
2.Java對(duì)象何時(shí)可用于垃圾收集?
當(dāng)對(duì)象被標(biāo)記為null、超出范圍或不再被應(yīng)用程序中的任何非null對(duì)象引用時(shí),它就可以進(jìn)行垃圾收集。簡(jiǎn)單來(lái)說,當(dāng)應(yīng)用程序不再使用Java對(duì)象時(shí),它就可以進(jìn)行垃圾收集。
3.標(biāo)記和掃描是什么意思?
可以將Java中的垃圾收集分為兩個(gè)主要階段。第一個(gè)階段是標(biāo)記階段,JVM查看內(nèi)存中的每個(gè)對(duì)象,并確定是否仍然需要它。如果不需要該對(duì)象,則將其標(biāo)記為垃圾收集。
掃描是第二階段,JVM在該階段執(zhí)行垃圾收集和內(nèi)存回收。
采用這種事件序列的垃圾收集算法稱為標(biāo)記和掃描垃圾收集器。
4.什么是分代垃圾回收?
JVM將分配的內(nèi)存拆分為四個(gè)獨(dú)立的空間:eden、survivor、tenured、metaspace。
底層JVM組件(如字符串緩沖區(qū)和編譯類)在元空間中分配內(nèi)存。隨著時(shí)間的推移,這個(gè)空間相對(duì)不變。當(dāng)人們談?wù)摾占瘯r(shí),重點(diǎn)通常是eden、survivor和tenured。
第一次創(chuàng)建對(duì)象時(shí),它會(huì)被放置在eden空間中。如果垃圾回收發(fā)生,并且對(duì)象仍然被引用,它將被移動(dòng)到survivor空間。如果發(fā)生了足夠多的垃圾收集,并且survivor空間中的某個(gè)對(duì)象從未被收集,那么它將被移動(dòng)到tenured空間。
eden、survivor和tenured空間都是單獨(dú)收集垃圾的,其中eden收集最多,tenured空間收集最少。這有助于提高性能,因?yàn)槿跏来僭O(shè)告訴我們,長(zhǎng)壽命對(duì)象可能會(huì)保持活動(dòng)狀態(tài),因此檢查其垃圾收集資格是浪費(fèi)時(shí)間。
此外,eden空間中的對(duì)象更有可能是短暫的,并且有資格被移除,因此掃描eden空間更有可能釋放出大量?jī)?nèi)存。
將垃圾收集器劃分為eden、survivor、Tentered和metaspace區(qū)域,可以極大地提高JVM性能。
5.Java內(nèi)存泄漏如何影響垃圾收集?
內(nèi)存泄漏會(huì)增加內(nèi)存消耗,JVM被迫更頻繁地運(yùn)行,以便為新對(duì)象清理空間。垃圾收集例程將更頻繁地運(yùn)行,每次運(yùn)行時(shí)釋放的內(nèi)存會(huì)更少,直到最終沒有剩余的堆空間。
6.什么時(shí)候會(huì)選擇并行垃圾收集器(GC)而不是并發(fā)標(biāo)記掃描(CMS)或G1垃圾收集器?
G1垃圾收集器在系統(tǒng)可以向堆分配大量?jī)?nèi)存時(shí)工作得最好。
在不影響應(yīng)用程序性能的情況下,使用CMS處理和垃圾收集例程。對(duì)于大小小于32GB的堆,它也最有效。
如果一個(gè)系統(tǒng)沒有大量專用于堆的內(nèi)存或多余的處理能力來(lái)分配給CMS,那么簡(jiǎn)單的并行GC是正確的選擇。
此外,與其他算法相比,并行GC通常會(huì)在給定的時(shí)間段內(nèi)收集更多的垃圾。如果暫停時(shí)間不是問題,那么并行垃圾收集可能是最佳選擇。
如果對(duì)垃圾回收行為較為敏感,那么深入了解垃圾回收的原則(以及它在 JVM 中是如何實(shí)現(xiàn)的)對(duì)于開發(fā)人員來(lái)說會(huì)很有幫助。
關(guān)鍵詞: 深入理解java垃圾回收