眾所周知,垃圾收集是影響性能的事情之一,所以我們應(yīng)該努力學(xué)習(xí)GC的基本知識(shí),特別是因?yàn)镴ava8在這一領(lǐng)域做了一些重大的更改和改進(jìn),尤其是隨著PermGen的刪除和一些新的令人興奮的優(yōu)化。通過(guò)參加java培訓(xùn),學(xué)習(xí)最新java技能,可以讓你的實(shí)力一直保持領(lǐng)先水平,提升行業(yè)競(jìng)爭(zhēng)力。
當(dāng)我們談?wù)摾占瘯r(shí),絕大多數(shù)人都知道這個(gè)概念,并在日常編程中使用它。即便如此,我們還是有很多不理解的地方。關(guān)于JVM最大的誤解之一是它有一個(gè)垃圾收集器,實(shí)際上它提供了四個(gè)不同的垃圾收集器,每個(gè)垃圾收集器都有自己獨(dú)特的優(yōu)點(diǎn)和缺點(diǎn)。選擇使用哪一個(gè)是由你自己決定的,吞吐量和應(yīng)用程序暫停之間的差異可能是巨大的。
這四種垃圾收集算法的共同點(diǎn)是,它們是分代的,這意味著它們將托管堆劃分為不同的部分,使用了一種古老的假設(shè),即堆中的大多數(shù)對(duì)象都是短暫的,應(yīng)該快速回收。
1.串行收集器
串行收集器是最簡(jiǎn)單的,也是你可能不會(huì)使用的,因?yàn)樗饕菫閱尉€程環(huán)境(例如32位或Windows)和小堆設(shè)計(jì)的。這個(gè)收集器在工作時(shí)會(huì)凍結(jié)所有應(yīng)用程序線程,這使得它在任何情況下都不能在服務(wù)器環(huán)境中使用。在java培訓(xùn)中,有很多關(guān)于Java開發(fā)工具、庫(kù)和框架的培訓(xùn)課程,在專業(yè)老師的教學(xué)指導(dǎo)下,可以很全面地掌握相關(guān)知識(shí)和技能。
如何使用它:你可以通過(guò)打開-XX:+UseSerialGCJVM參數(shù)來(lái)使用它
2.并行/吞吐量收集器
接下來(lái)是并行收集器。這是JVM的默認(rèn)收集器。就像它的名字一樣,它最大的優(yōu)點(diǎn)是使用多個(gè)線程來(lái)掃描和壓縮堆。并行收集器的缺點(diǎn)是,當(dāng)執(zhí)行次要或完整GC收集時(shí),它將停止應(yīng)用程序線程。并行收集器最適合那些可以容忍應(yīng)用程序暫停并試圖優(yōu)化收集器導(dǎo)致的較低CPU開銷的應(yīng)用程序。
3.CMS收集器
并行收集器的后續(xù)是CMS收集器(“并發(fā)標(biāo)記掃描”)。該算法使用多個(gè)線程(“并發(fā)”)在堆中掃描(“標(biāo)記”)可回收的未使用對(duì)象(“掃描”)。在兩種情況下,該算法將進(jìn)入“停止世界”(STW)模式:當(dāng)初始化根(舊一代中可以從線程入口點(diǎn)或靜態(tài)變量訪問(wèn)的對(duì)象)的初始標(biāo)記時(shí),以及當(dāng)應(yīng)用程序在算法同時(shí)運(yùn)行時(shí)更改了堆的狀態(tài)時(shí),迫使它返回并做一些最后的潤(rùn)色,以確保它標(biāo)記了正確的對(duì)象。對(duì)Java感興趣的同學(xué)可以參加java培訓(xùn),可以獲得快速有效的學(xué)習(xí)。
使用此收集器時(shí),最大的問(wèn)題是遇到升級(jí)失敗,即在收集年輕一代和老年一代之間發(fā)生競(jìng)爭(zhēng)的情況。如果收集器需要將年輕的對(duì)象提升到舊一代,但沒(méi)有足夠的時(shí)間騰出空間來(lái)清除它,它將不得不首先這樣做,這將導(dǎo)致完整的STW收集——這正是CMS收集器想要防止的事情。為了確保這種情況不會(huì)發(fā)生,你可以增加舊一代的大小(或者整個(gè)堆的大小),或者為收集器分配更多的后臺(tái)線程,讓他與對(duì)象分配的速率競(jìng)爭(zhēng)。
與并行收集器相比,該算法的另一個(gè)缺點(diǎn)是,它使用更多的CPU,通過(guò)使用多個(gè)線程執(zhí)行掃描和收集,為應(yīng)用程序提供更高級(jí)別的連續(xù)吞吐量。對(duì)于大多數(shù)不利于應(yīng)用程序凍結(jié)的長(zhǎng)期運(yùn)行的服務(wù)器應(yīng)用程序,這通常是一個(gè)很好的權(quán)衡。即便如此,該算法在默認(rèn)情況下也不會(huì)啟用。你必須指定XX:+USeParNewGC才能真正啟用它。如果你愿意分配更多的CPU資源來(lái)避免應(yīng)用程序暫停,假設(shè)你的堆大小小于4Gb,這就是你可能想要使用的收集器。然而,如果它大于4GB,你可能會(huì)想使用最后一種算法——G1收集器。想學(xué)習(xí)java技術(shù)的同學(xué),不妨報(bào)個(gè)Java培訓(xùn)班,有明確清晰的學(xué)習(xí)路線,理論知識(shí)+實(shí)戰(zhàn)操作,可以獲得快速提升。
4.G1收集器
JDK7更新4中引入的垃圾優(yōu)先收集器(G1)旨在更好地支持大于4GB的堆。G1收集器利用多個(gè)后臺(tái)線程來(lái)掃描它劃分為區(qū)域的堆,范圍從1MB到32MB(取決于堆的大小)。G1收集器旨在首先掃描那些包含最多垃圾對(duì)象的區(qū)域,并將其命名為(垃圾優(yōu)先)。此收集器是使用–XX:+UseG1GC標(biāo)志打開的。
此策略降低了在后臺(tái)線程完成對(duì)未使用對(duì)象的掃描之前堆被耗盡的可能性,在這種情況下,收集器將不得不停止應(yīng)用程序,這將導(dǎo)致STW收集。G1還有另一個(gè)優(yōu)點(diǎn),那就是它在移動(dòng)中壓縮了堆,而CMS收集器只在完整的STW收集過(guò)程中才這樣做。在java培訓(xùn)中,不僅有理論知識(shí)的課程,還有大量實(shí)戰(zhàn)項(xiàng)目學(xué)習(xí),讓你在實(shí)踐中真正掌握J(rèn)ava知識(shí)和技能。
在過(guò)去的幾年里,大型堆一直是一個(gè)相當(dāng)有爭(zhēng)議的領(lǐng)域,許多開發(fā)人員從每臺(tái)機(jī)器的單個(gè)JVM模型轉(zhuǎn)向每臺(tái)機(jī)器有多個(gè)JVM的更微服務(wù)、組件化的架構(gòu)。這是由許多因素驅(qū)動(dòng)的,包括希望隔離不同的應(yīng)用程序部分,簡(jiǎn)化部署,避免將應(yīng)用程序類重新加載到內(nèi)存中通常會(huì)帶來(lái)的成本(這在Java8中實(shí)際上得到了改進(jìn))。
即便如此,在JVM中,這樣做的最大驅(qū)動(dòng)因素之一源于避免大型堆中出現(xiàn)的長(zhǎng)時(shí)間“停止世界”暫停(在大型集合中可能需要幾秒鐘)的愿望。Docker等容器技術(shù)也加速了這一進(jìn)程,使你能夠相對(duì)輕松地在同一物理機(jī)器上部署多個(gè)應(yīng)用程序。
總結(jié)
這些收集器中的每一個(gè)都通過(guò)一系列切換和開關(guān)進(jìn)行了不同的配置和調(diào)整,每個(gè)都有可能增加或減少吞吐量,所有這些都基于你的應(yīng)用程序的特定行為。參加java培訓(xùn)是入門學(xué)習(xí)的最佳選擇,有經(jīng)驗(yàn)豐富的專業(yè)老師面授指導(dǎo)教學(xué),通過(guò)理論結(jié)合實(shí)戰(zhàn)的方式教授java基礎(chǔ)知識(shí),幫助你更好的理解與運(yùn)用java。