摘要:深入理解虛擬機(jī)高級(jí)特性與最佳實(shí)踐第二版讀書(shū)筆記與常見(jiàn)面試題總結(jié)上篇文章傳送門(mén)深入理解虛擬機(jī)之內(nèi)存區(qū)域本節(jié)常見(jiàn)面試題推薦帶著問(wèn)題閱讀,問(wèn)題答案在文中都有提到如何判斷對(duì)象是否死亡兩種方法。虛引用主要用來(lái)跟蹤對(duì)象被垃圾回收的活動(dòng)。
《深入理解Java虛擬機(jī):JVM高級(jí)特性與最佳實(shí)踐(第二版》讀書(shū)筆記與常見(jiàn)面試題總結(jié)
上篇文章傳送門(mén):
深入理解虛擬機(jī)之Java內(nèi)存區(qū)域
本節(jié)常見(jiàn)面試題(推薦帶著問(wèn)題閱讀,問(wèn)題答案在文中都有提到):
如何判斷對(duì)象是否死亡(兩種方法)。
簡(jiǎn)單的介紹一下強(qiáng)引用、軟引用、弱引用、虛引用(虛引用與軟引用和弱引用的區(qū)別、使用軟引用能帶來(lái)的好處)。
垃圾收集有哪些算法,各自的特點(diǎn)?
HotSpot為什么要分為新生代和老年代?
常見(jiàn)的垃圾回收器有那些?
介紹一下CMS,G1收集器。
Minor Gc和Full GC 有什么不同呢?
1 概述首先所需要考慮:
那些垃圾需要回收?
什么時(shí)候回收?
如何回收?
當(dāng)需要排查各種 內(nèi)存溢出問(wèn)題、當(dāng)垃圾收集稱為系統(tǒng)達(dá)到更高并發(fā)的瓶頸時(shí),我們就需要對(duì)這些“自動(dòng)化”的技術(shù)實(shí)施必要的監(jiān)控和調(diào)節(jié)。
2 對(duì)象已經(jīng)死亡?堆中幾乎放著所有的對(duì)象實(shí)例,對(duì)堆垃圾回收前的第一步就是要判斷那些對(duì)象已經(jīng)死亡(即不能再被任何途徑使用的對(duì)象)
2.1引用計(jì)數(shù)法給對(duì)象中添加一個(gè)引用計(jì)數(shù)器,每當(dāng)有一個(gè)地方引用它,計(jì)數(shù)器就加1;當(dāng)引用失效,計(jì)數(shù)器就減1;任何時(shí)候計(jì)數(shù)器為0的對(duì)象就是不可能再被使用的。
這個(gè)方法實(shí)現(xiàn)簡(jiǎn)單,效率高,但是目前主流的虛擬機(jī)中并沒(méi)有選擇這個(gè)算法來(lái)管理內(nèi)存,其最主要的原因是它很難解決對(duì)象之間相互循環(huán)引用的問(wèn)題。
2.2可達(dá)性分析算法這個(gè)算法的基本思想就是通過(guò)一系列的稱為 “GC Roots” 的對(duì)象作為起點(diǎn),從這些節(jié)點(diǎn)開(kāi)始向下搜索,節(jié)點(diǎn)所走過(guò)的路徑稱為引用鏈,當(dāng)一個(gè)對(duì)象到GC Roots沒(méi)有任何引用鏈相連的話,則證明此對(duì)象是不可用的。
JDK1.2以后,Java對(duì)引用的感念進(jìn)行了擴(kuò)充,將引用分為強(qiáng)引用、軟引用、弱引用、虛引用四種(引用強(qiáng)度逐漸減弱)
1.強(qiáng)引用
以前我們使用的大部分引用實(shí)際上都是強(qiáng)引用,這是使用最普遍的引用。如果一個(gè)對(duì)象具有強(qiáng)引用,那就類(lèi)似于必不可少的生活用品,垃圾回收器絕不會(huì)回收它。當(dāng)內(nèi)存空 間不足,Java虛擬機(jī)寧愿拋出OutOfMemoryError錯(cuò)誤,使程序異常終止,也不會(huì)靠隨意回收具有強(qiáng)引用的對(duì)象來(lái)解決內(nèi)存不足問(wèn)題。
2.軟引用(SoftReference)
如果一個(gè)對(duì)象只具有軟引用,那就類(lèi)似于可有可物的生活用品。如果內(nèi)存空間足夠,垃圾回收器就不會(huì)回收它,如果內(nèi)存空間不足了,就會(huì)回收這些對(duì)象的內(nèi)存。只要垃圾回收器沒(méi)有回收它,該對(duì)象就可以被程序使用。軟引用可用來(lái)實(shí)現(xiàn)內(nèi)存敏感的高速緩存。
軟引用可以和一個(gè)引用隊(duì)列(ReferenceQueue)聯(lián)合使用,如果軟引用所引用的對(duì)象被垃圾回收,JAVA虛擬機(jī)就會(huì)把這個(gè)軟引用加入到與之關(guān)聯(lián)的引用隊(duì)列中。
3.弱引用(WeakReference)
如果一個(gè)對(duì)象只具有弱引用,那就類(lèi)似于可有可物的生活用品。弱引用與軟引用的區(qū)別在于:只具有弱引用的對(duì)象擁有更短暫的生命周期。在垃圾回收器線程掃描它 所管轄的內(nèi)存區(qū)域的過(guò)程中,一旦發(fā)現(xiàn)了只具有弱引用的對(duì)象,不管當(dāng)前內(nèi)存空間足夠與否,都會(huì)回收它的內(nèi)存。不過(guò),由于垃圾回收器是一個(gè)優(yōu)先級(jí)很低的線程, 因此不一定會(huì)很快發(fā)現(xiàn)那些只具有弱引用的對(duì)象。
弱引用可以和一個(gè)引用隊(duì)列(ReferenceQueue)聯(lián)合使用,如果弱引用所引用的對(duì)象被垃圾回收,Java虛擬機(jī)就會(huì)把這個(gè)弱引用加入到與之關(guān)聯(lián)的引用隊(duì)列中。
4.虛引用(PhantomReference)
"虛引用"顧名思義,就是形同虛設(shè),與其他幾種引用都不同,虛引用并不會(huì)決定對(duì)象的生命周期。如果一個(gè)對(duì)象僅持有虛引用,那么它就和沒(méi)有任何引用一樣,在任何時(shí)候都可能被垃圾回收。
虛引用主要用來(lái)跟蹤對(duì)象被垃圾回收的活動(dòng)。
虛引用與軟引用和弱引用的一個(gè)區(qū)別在于: 虛引用必須和引用隊(duì)列(ReferenceQueue)聯(lián)合使用。當(dāng)垃 圾回收器準(zhǔn)備回收一個(gè)對(duì)象時(shí),如果發(fā)現(xiàn)它還有虛引用,就會(huì)在回收對(duì)象的內(nèi)存之前,把這個(gè)虛引用加入到與之關(guān)聯(lián)的引用隊(duì)列中。程序可以通過(guò)判斷引用隊(duì)列中是 否已經(jīng)加入了虛引用,來(lái)了解被引用的對(duì)象是否將要被垃圾回收。程序如果發(fā)現(xiàn)某個(gè)虛引用已經(jīng)被加入到引用隊(duì)列,那么就可以在所引用的對(duì)象的內(nèi)存被回收之前采取必要的行動(dòng)。
特別注意,在程序設(shè)計(jì)中一般很少使用弱引用與虛引用,使用軟引用的情況較多,這是因?yàn)?strong>軟引用可以加速JVM對(duì)垃圾內(nèi)存的回收速度,可以維護(hù)系統(tǒng)的運(yùn)行安全,防止內(nèi)存溢出(OutOfMemory)等問(wèn)題的產(chǎn)生。
2.4 生存還是死亡即使在可達(dá)性分析法中不可達(dá)的對(duì)象,也并非是“非死不可”的,這時(shí)候它們暫時(shí)處于“緩刑階段”,要真正宣告一個(gè)對(duì)象死亡,至少要經(jīng)歷兩次標(biāo)記過(guò)程;可達(dá)性分析法中不可達(dá)的對(duì)象被第一次標(biāo)記并且進(jìn)行一次篩選,篩選的條件是此對(duì)象是否有必要執(zhí)行finalize方法。當(dāng)對(duì)象沒(méi)有覆蓋finalize方法,或finalize方法已經(jīng)被虛擬機(jī)調(diào)用過(guò)時(shí),虛擬機(jī)將這兩種情況視為沒(méi)有必要執(zhí)行。被判定為需要執(zhí)行的對(duì)象將會(huì)被放在一個(gè)隊(duì)列中進(jìn)行第二次標(biāo)記,除非這個(gè)對(duì)象與引用鏈上的任何一個(gè)對(duì)象建立關(guān)聯(lián),否則就會(huì)被真的回收。
2.5 回收方法區(qū)方法區(qū)(或Hotspot虛擬中的永久代)的垃圾收集主要回收兩部分內(nèi)容:廢棄常量和無(wú)用的類(lèi)。
判定一個(gè)常量是否是“廢棄常量”比較簡(jiǎn)單,而要判定一個(gè)類(lèi)是否是“無(wú)用的類(lèi)”的條件則相對(duì)苛刻許多。類(lèi)需要同時(shí)滿足下面3個(gè)條件才能算是 “無(wú)用的類(lèi)” :
該類(lèi)所有的實(shí)例都已經(jīng)被回收,也就是Java堆中不存在該類(lèi)的任何實(shí)例。
加載該類(lèi)的ClassLoader已經(jīng)被回收。
該類(lèi)對(duì)應(yīng)的java.lang.Class對(duì)象沒(méi)有在任何地方被引用,無(wú)法在任何地方通過(guò)反射訪問(wèn)該類(lèi)的方法。
3 垃圾收集算法 3.1 標(biāo)記-清除算法算法分為“標(biāo)記”和“清除”階段:首先標(biāo)記出所有需要回收的對(duì)象,在標(biāo)記完成后統(tǒng)一回收所有被標(biāo)記的對(duì)象。它是最基礎(chǔ)的收集算法,會(huì)帶來(lái)兩個(gè)明顯的問(wèn)題;1:效率問(wèn)題和2:空間問(wèn)題(標(biāo)記清除后會(huì)產(chǎn)生大量不連續(xù)的碎片)
為了解決效率問(wèn)題,“復(fù)制”收集算法出現(xiàn)了。它可以將內(nèi)存分為大小相同的兩塊,每次使用其中的一塊。當(dāng)這一塊的內(nèi)存使用完后,就將還存活的對(duì)象復(fù)制到另一塊去,然后再把使用的空間一次清理掉。這樣就使每次的內(nèi)存回收都是對(duì)內(nèi)存區(qū)間的一半進(jìn)行回收。
3.3 標(biāo)記-整理算法根據(jù)老年代的特點(diǎn)特出的一種標(biāo)記算法,標(biāo)記過(guò)程仍然與“標(biāo)記-清除”算法一樣,但后續(xù)步驟不是直接對(duì)可回收對(duì)象回收,而是讓所有存活的對(duì)象向一段移動(dòng),然后直接清理掉端邊界以外的內(nèi)存。
3.4分代收集算法當(dāng)前虛擬機(jī)的垃圾手機(jī)都采用分代收集算法,這種算法沒(méi)有什么新的思想,只是根據(jù)對(duì)象存活周期的不同將內(nèi)存分為幾塊。一般將java堆分為新生代和老年代,這樣我們就可以根據(jù)各個(gè)年代的特點(diǎn)選擇合適的垃圾收集算法。
比如在新生代中,每次收集都會(huì)有大量對(duì)象死去,所以可以選擇復(fù)制算法,只需要付出少量對(duì)象的復(fù)制成本就可以完成每次垃圾收集。而老年代的對(duì)象存活幾率是比較高的所以我們可以選擇“標(biāo)記-清理”或“標(biāo)記-整理”算法進(jìn)行垃圾收集。
延伸面試問(wèn)題: HotSpot為什么要分為新生代和老年代?
根據(jù)上面的對(duì)分代收集算法的介紹回答。
4 垃圾收集器如果說(shuō)收集算法是內(nèi)存回收的方法論,那么垃圾收集器就是內(nèi)存回收的具體實(shí)現(xiàn)。
雖然我們對(duì)各個(gè)收集器進(jìn)行比較,但并非了挑選出一個(gè)最好的收集器。因?yàn)橹垃F(xiàn)在位置還沒(méi)有最好的垃圾收集器出現(xiàn),更加沒(méi)有萬(wàn)能的垃圾收集器,我們能做的就是根據(jù)具體應(yīng)用場(chǎng)景選擇適合自己的垃圾收集器。試想一下:如果有一種四海之內(nèi)、任何場(chǎng)景下都適用的完美收集器存在,那么我們的HotSpot虛擬機(jī)就不會(huì)實(shí)現(xiàn)那么多不同的垃圾收集器了。
Serial(串行)收集器收集器是最基本、歷史最悠久的垃圾收集器了。大家看名字就知道這個(gè)收集器是一個(gè)單線程收集器了。它的 “單線程” 的意義不僅僅意味著它只會(huì)使用一條垃圾收集線程去完成垃圾收集工作,更重要的是它在進(jìn)行垃圾收集工作的時(shí)候必須暫停其他所有的工作線程( "Stop The World" 了解一下),直到它收集結(jié)束。
虛擬機(jī)的設(shè)計(jì)者們當(dāng)然知道Stop The World帶來(lái)的不良用戶體驗(yàn),所以在后續(xù)的垃圾收集器設(shè)計(jì)中停頓時(shí)間在不斷縮短(仍然還有停頓,尋找最優(yōu)秀的垃圾收集器的過(guò)程仍然在繼續(xù))。
但是Serial收集器有沒(méi)有優(yōu)于其他垃圾收集器的地方呢?當(dāng)然有,它簡(jiǎn)單而高效(與其他收集器的單線程相比)。Serial收集器由于沒(méi)有線程交互的開(kāi)銷(xiāo),自然可以獲得很高的單線程收集效率。Serial收集器對(duì)于運(yùn)行在Client模式下的虛擬機(jī)來(lái)說(shuō)是個(gè)不錯(cuò)的選擇。
4.2 ParNew收集器ParNew收集器其實(shí)就是Serial收集器的多線程版本,除了使用多線程進(jìn)行垃圾收集外,其余行為(控制參數(shù)、收集算法、回收策略等等)和Serial收集器完全一樣。
它是許多運(yùn)行在Server模式下的虛擬機(jī)的首要選擇,除了Serial收集器外,只有它能與CMS收集器(真正意義上的并發(fā)收集器,后面會(huì)介紹到)配合工作。
并行和并發(fā)概念補(bǔ)充:
并行(Parallel) :指多條垃圾收集線程并行工作,但此時(shí)用戶線程仍然處于等待狀態(tài)。
并發(fā)(Concurrent):指用戶線程與垃圾收集線程同時(shí)執(zhí)行(但不一定是并行,可能會(huì)交替執(zhí)行),用戶程序在繼續(xù)運(yùn)行,而垃圾收集器運(yùn)行在另一個(gè)CPU上。
4.3 Parallel Scavenge收集器Parallel Scavenge收集器是一個(gè)新生代收集器,它也是使用復(fù)制算法的收集器,又是并行的的多線程收集器。。。那么它有什么特別之處呢?
Parallel Scavenge收集器關(guān)注點(diǎn)是吞吐量(高效率的利用CPU)。CMS等垃圾收集器的關(guān)注點(diǎn)更多的是用戶線程的停頓時(shí)間(提高用戶體驗(yàn))。所謂吞吐量就是CPU中用于運(yùn)行用戶代碼的時(shí)間與CPU總消耗時(shí)間的比值。 Parallel Scavenge收集器提供了很多參數(shù)供用戶找到最合適的停頓時(shí)間或最大吞吐量,如果對(duì)于收集器運(yùn)作不太了解的話,手工優(yōu)化存在的話可以選擇把內(nèi)存管理優(yōu)化交給虛擬機(jī)去完成也是一個(gè)不錯(cuò)的選擇。
4.4.Serial Old收集器Serial收集器的老年代版本,它同樣是一個(gè)單線程收集器。它主要有兩大用途:一種用途是在JDK1.5以及以前的版本中與Parallel Scavenge收集器搭配使用,另一種用途是作為CMS收集器的后備方案。
4.5 Parallel Old收集器Parallel Scavenge收集器的老年代版本。使用多線程和“標(biāo)記-整理”算法。在注重吞吐量以及CPU資源的場(chǎng)合,都可以優(yōu)先考慮 Parallel Scavenge收集器和Parallel Old收集器。
4.6 CMS收集器CMS(Concurrent Mark Sweep)收集器是一種以獲取最短回收停頓時(shí)間為目標(biāo)的收集器。它而非常符合在注重用戶體驗(yàn)的應(yīng)用上使用。
從名字中的Mark Sweep這兩個(gè)詞可以看出,CMS收集器是一種 “標(biāo)記-清除”算法實(shí)現(xiàn)的,它的運(yùn)作過(guò)程相比于前面幾種垃圾收集器來(lái)說(shuō)更加復(fù)雜一些。整個(gè)過(guò)程分為四個(gè)步驟:
初始標(biāo)記: 暫停所有的其他線程,并記錄下直接與root相連的對(duì)象,速度很快 ;
并發(fā)標(biāo)記: 同時(shí)開(kāi)啟GC和用戶線程,用一個(gè)閉包結(jié)構(gòu)去記錄可達(dá)對(duì)象。但在這個(gè)階段結(jié)束,這個(gè)閉包結(jié)構(gòu)并不能保證包含當(dāng)前所有的可達(dá)對(duì)象。因?yàn)橛脩艟€程可能會(huì)不斷的更新引用域,所以GC線程無(wú)法保證可達(dá)性分析的實(shí)時(shí)性。所以這個(gè)算法里會(huì)跟蹤記錄這些發(fā)生引用更新的地方。
重新標(biāo)記: 重新標(biāo)記階段就是為了修正并發(fā)標(biāo)記期間因?yàn)橛脩舫绦蚶^續(xù)運(yùn)行而導(dǎo)致標(biāo)記產(chǎn)生變動(dòng)的那一部分對(duì)象的標(biāo)記記錄,這個(gè)階段的停頓時(shí)間一般會(huì)比初始標(biāo)記階段的時(shí)間稍長(zhǎng),遠(yuǎn)遠(yuǎn)比并發(fā)標(biāo)記階段時(shí)間短
并發(fā)清除: 開(kāi)啟用戶線程,同時(shí)GC線程開(kāi)始對(duì)為標(biāo)記的區(qū)域做清掃。
從它的名字就可以看出它是一款優(yōu)秀的垃圾收集器,主要優(yōu)點(diǎn):并發(fā)收集、低停頓。但是它有下面三個(gè)明顯的缺點(diǎn):
對(duì)CPU資源敏感;
無(wú)法處理浮動(dòng)垃圾;
它使用的回收算法-“標(biāo)記-清除”算法會(huì)導(dǎo)致收集結(jié)束時(shí)會(huì)有大量空間碎片產(chǎn)生。
4.7 G1收集器上一代的垃圾收集器(串行serial, 并行parallel, 以及CMS)都把堆內(nèi)存劃分為固定大小的三個(gè)部分: 年輕代(young generation), 年老代(old generation), 以及持久代(permanent generation).
G1 (Garbage-First)是一款面向服務(wù)器的垃圾收集器,主要針對(duì)配備多顆處理器及大容量?jī)?nèi)存的機(jī)器. 以極高概率滿足GC停頓時(shí)間要求的同時(shí),還具備高吞吐量性能特征.
被視為JDK1.7中HotSpot虛擬機(jī)的一個(gè)重要進(jìn)化特征。它具備一下特點(diǎn):
并行與并發(fā):G1能充分利用CPU、多核環(huán)境下的硬件優(yōu)勢(shì),使用多個(gè)CPU(CPU或者CPU核心)來(lái)縮短stop-The-World停頓時(shí)間。部分其他收集器原本需要停頓Java線程執(zhí)行的GC動(dòng)作,G1收集器仍然可以通過(guò)并發(fā)的方式讓java程序繼續(xù)執(zhí)行。
分代收集:雖然G1可以不需要其他收集器配合就能獨(dú)立管理整個(gè)GC堆,但是還是保留了分代的概念。
空間整合:與CMS的“標(biāo)記--清理”算法不同,G1從整體來(lái)看是基于“標(biāo)記整理”算法實(shí)現(xiàn)的收集器;從局部上來(lái)看是基于“復(fù)制”算法實(shí)現(xiàn)的。
可預(yù)測(cè)的停頓:這是G1相對(duì)于CMS的另一個(gè)大優(yōu)勢(shì),降低停頓時(shí)間是G1和CMS共同的關(guān)注點(diǎn),但G1除了追求低停頓外,還能建立可預(yù)測(cè)的停頓時(shí)間模型,能讓使用者明確指定在一個(gè)長(zhǎng)度為M毫秒的時(shí)間片段內(nèi)。
G1收集器在后臺(tái)維護(hù)了一個(gè)優(yōu)先列表,每次根據(jù)允許的收集時(shí)間,優(yōu)先選擇回收價(jià)值最大的Region(這也就是它的名字Garbage-First的由來(lái))。這種使用Region劃分內(nèi)存空間以及有優(yōu)先級(jí)的區(qū)域回收方式,保證了GF收集器在有限時(shí)間內(nèi)可以盡可能高的收集效率(把內(nèi)存化整為零)。
G1收集器的運(yùn)作大致分為以下幾個(gè)步驟:
初始標(biāo)記
并發(fā)標(biāo)記
最終標(biāo)記
篩選回收
上面幾個(gè)步驟的運(yùn)作過(guò)程和CMS有很多相似之處。初始標(biāo)記階段僅僅只是標(biāo)記一下GC Roots能直接關(guān)聯(lián)到的對(duì)象,并且修改TAMS的值,讓下一個(gè)階段用戶程序并發(fā)運(yùn)行時(shí),能在正確可用的Region中創(chuàng)建新對(duì)象,這一階段需要停頓線程,但是耗時(shí)很短,并發(fā)標(biāo)記階段是從GC Root開(kāi)始對(duì)堆中對(duì)象進(jìn)行可達(dá)性分析,找出存活的對(duì)象,這階段時(shí)耗時(shí)較長(zhǎng),但可與用戶程序并發(fā)執(zhí)行。而最終標(biāo)記階段則是為了修正在并發(fā)標(biāo)記期間因用戶程序繼續(xù)運(yùn)作而導(dǎo)致標(biāo)記產(chǎn)生變動(dòng)的那一部分標(biāo)記記錄,虛擬機(jī)將這段時(shí)間對(duì)象變化記錄在線程Remenbered Set Logs里面,最終標(biāo)記階段需要把Remembered Set Logs的數(shù)據(jù)合并到Remembered Set Logs里面,最終標(biāo)記階段需要把Remembered Set Logs的數(shù)據(jù)合并到Remembered Set中,這一階段需要停頓線程,但是可并行執(zhí)行。最后在篩選回收階段首先對(duì)各個(gè)Region的回收價(jià)值和成本進(jìn)行排序,根據(jù)用戶所期望的GC停頓時(shí)間來(lái)制定回收計(jì)劃。
5 內(nèi)存分配與回收策略 5.1對(duì)象優(yōu)先在Eden區(qū)分配大多數(shù)情況下,對(duì)象在新生代中Eden區(qū)分配。當(dāng)Eden區(qū)沒(méi)有足夠空間進(jìn)行分配時(shí),虛擬機(jī)將發(fā)起一次Minor GC.
Minor Gc和Full GC 有什么不同呢?
新生代GC(Minor GC):指發(fā)生新生代的的垃圾收集動(dòng)作,Minor GC非常頻繁,回收速度一般也比較快。
老年代GC(Major GC/Full GC):指發(fā)生在老年代的GC,出現(xiàn)了Major GC經(jīng)常會(huì)伴隨至少一次的Minor GC(并非絕對(duì)),Major GC的速度一般會(huì)比Minor GC的慢10倍以上。
5.2 大對(duì)象直接進(jìn)入老年代大對(duì)象就是需要大量連續(xù)內(nèi)存空間的對(duì)象(比如:字符串、數(shù)組)。
5.3長(zhǎng)期存活的對(duì)象將進(jìn)入老年代既然虛擬機(jī)采用了分代收集的思想來(lái)管理內(nèi)存,那么內(nèi)存回收時(shí)就必須能識(shí)別那些對(duì)象應(yīng)放在新生代,那些對(duì)象應(yīng)放在老年代中。為了做到這一點(diǎn),虛擬機(jī)給每個(gè)對(duì)象一個(gè)對(duì)象年齡(Age)計(jì)數(shù)器。
5.4 動(dòng)態(tài)對(duì)象年齡判定為了更好的適應(yīng)不同程序的內(nèi)存情況,虛擬機(jī)不是永遠(yuǎn)要求對(duì)象年齡必須達(dá)到了某個(gè)值才能進(jìn)入老年代,如果Survivor 空間中相同年齡所有對(duì)象大小的總和大于Survivor空間的一半,年齡大于或等于該年齡的對(duì)象就可以直接進(jìn)入老年代,無(wú)需達(dá)到要求的年齡。
總結(jié):本節(jié)介紹了垃圾收集算法,幾款JDK1.7中提供的垃圾收集器特點(diǎn)以及運(yùn)作原理。
內(nèi)存回收與垃圾收集器在很多時(shí)候都是影響系統(tǒng)性能、并發(fā)能力的主要因素之一,虛擬機(jī)之所以提供多種不同的收集器以及大量調(diào)節(jié)參數(shù),是因?yàn)橹挥懈鶕?jù)實(shí)際應(yīng)用的需求、實(shí)現(xiàn)方式選擇最優(yōu)的收集方式才能獲取最高的性能。沒(méi)有固定收集器、參數(shù)組合、也沒(méi)有最優(yōu)的調(diào)優(yōu)方法,那么必須了解每一個(gè)具體收集器的行為、優(yōu)勢(shì)和劣勢(shì)、調(diào)節(jié)參數(shù)。
歡迎關(guān)注我的微信公眾號(hào):"Java面試通關(guān)手冊(cè)"(一個(gè)有溫度的微信公眾號(hào),期待與你共同進(jìn)步~~~堅(jiān)持原創(chuàng),分享美文,分享各種Java學(xué)習(xí)資源):
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/69345.html
摘要:運(yùn)行時(shí)數(shù)據(jù)區(qū)域虛擬機(jī)在執(zhí)行程序的過(guò)程中會(huì)把它管理的內(nèi)存劃分成若干個(gè)不同的數(shù)據(jù)區(qū)域。堆虛擬機(jī)所管理的內(nèi)存中最大的一塊,堆是所有線程共享的一塊內(nèi)存區(qū)域,在虛擬機(jī)啟動(dòng)時(shí)創(chuàng)建。 《深入理解Java虛擬機(jī):JVM高級(jí)特性與最佳實(shí)踐(第二版》讀書(shū)筆記 1 概述 對(duì)于Java程序員來(lái)說(shuō),在虛擬機(jī)自動(dòng)內(nèi)存管理機(jī)制下,不再需要像C/C++程序開(kāi)發(fā)程序員這樣為內(nèi)一個(gè)new 操作去寫(xiě)對(duì)應(yīng)的delete/...
摘要:深入理解虛擬機(jī)高級(jí)特性與最佳實(shí)踐第二版讀書(shū)筆記與常見(jiàn)面試題總結(jié)本節(jié)常見(jiàn)面試題介紹下內(nèi)存區(qū)域運(yùn)行時(shí)數(shù)據(jù)區(qū)。運(yùn)行時(shí)數(shù)據(jù)區(qū)域虛擬機(jī)在執(zhí)行程序的過(guò)程中會(huì)把它管理的內(nèi)存劃分成若干個(gè)不同的數(shù)據(jù)區(qū)域。 《深入理解Java虛擬機(jī):JVM高級(jí)特性與最佳實(shí)踐(第二版》讀書(shū)筆記與常見(jiàn)面試題總結(jié) 本節(jié)常見(jiàn)面試題: 介紹下Java內(nèi)存區(qū)域(運(yùn)行時(shí)數(shù)據(jù)區(qū))。 對(duì)象的訪問(wèn)定位的兩種方式。 1 概述 對(duì)于Java...
摘要:監(jiān)控和故障處理工具顯示指定系統(tǒng)內(nèi)所有的虛擬機(jī)進(jìn)程用于收集虛擬機(jī)各方面的運(yùn)行數(shù)據(jù)。的常用功能選項(xiàng)測(cè)試上面輸出了我正在運(yùn)行程序的包名下的類(lèi)名虛擬機(jī)統(tǒng)計(jì)信息監(jiān)視工具使用于監(jiān)視虛擬機(jī)各種運(yùn)行狀態(tài)信息的命令行工具。 《深入理解Java虛擬機(jī):JVM高級(jí)特性與最佳實(shí)踐(第二版》讀書(shū)筆記與常見(jiàn)面試題總結(jié) 本節(jié)常見(jiàn)面試題(推薦帶著問(wèn)題閱讀,問(wèn)題答案在文中都有提到): JVM調(diào)優(yōu)的常見(jiàn)命令行工具有哪些?...
摘要:今天開(kāi)始實(shí)戰(zhàn)虛擬機(jī)之三的新生代。一旦區(qū)被占滿,新生代就會(huì)啟動(dòng)。新生代收集前后的堆數(shù)據(jù)如圖所示,其中表示區(qū),表示區(qū),表示老年代。當(dāng)然我們最為關(guān)心的依然是的停頓時(shí)間以及回收情況。節(jié)選自實(shí)戰(zhàn)虛擬機(jī)一書(shū)交流群 今天開(kāi)始實(shí)戰(zhàn)Java虛擬機(jī)之三:G1的新生代GC。 總計(jì)有5個(gè)系列實(shí)戰(zhàn)Java虛擬機(jī)之一堆溢出處理實(shí)戰(zhàn)Java虛擬機(jī)之二虛擬機(jī)的工作模式實(shí)戰(zhàn)Java虛擬機(jī)之三G1的新生代GC實(shí)戰(zhàn)Java...
摘要:當(dāng)兩個(gè)對(duì)象相互引用時(shí),這兩個(gè)對(duì)象就不會(huì)被回收引用計(jì)數(shù)算法不被主流虛擬機(jī)采用,主要原因是它很難解決對(duì)象之間相互循環(huán)引用的問(wèn)題。 垃圾收集器與內(nèi)存分配策略 詳解 3.1 概述 本文參考的是周志明的 《深入理解Java虛擬機(jī)》第三章 ,為了整理思路,簡(jiǎn)單記錄一下,方便后期查閱。 3.2 對(duì)象已死嗎 在垃圾收集器進(jìn)行回收前,第一件事就是確定這些對(duì)象哪些還存活,哪些已經(jīng)死去。 3.2.1 引用...
閱讀 1075·2023-04-26 02:02
閱讀 2416·2021-09-26 10:11
閱讀 3569·2019-08-30 13:10
閱讀 3758·2019-08-29 17:12
閱讀 732·2019-08-29 14:20
閱讀 2199·2019-08-28 18:19
閱讀 2245·2019-08-26 13:52
閱讀 969·2019-08-26 13:43