Java之JVM垃圾回收 內(nèi)存結(jié)構(gòu)以及垃圾回收算法
作為Java語言的核心之一向拆,JVM垃圾回收幫我們解決了讓我們很頭疼的垃圾回收問題萌朱。我們不需要像VC++一樣,作為內(nèi)存管理的統(tǒng)治者需要我們對我們分配的每一塊內(nèi)存進行回收,否則就會造成內(nèi)存泄露問題于置。
是不是只要有JVM存在我們就不會出現(xiàn)內(nèi)存泄露問題,出現(xiàn)內(nèi)存泄露問題我們又該怎么辦贞岭,如果我們想提高我們程序的穩(wěn)定性和其他性能我們能從什么地方下手0颂骸!瞄桨!相信這些問題是我們程序過程中不可逾越的话速。了解JVM的內(nèi)存分配及其相應(yīng)的垃圾回收機制,不僅僅是可以了解底層的JVM運行機制芯侥,而且對于程序性能的優(yōu)化和提升還是很有必要的泊交。
一.JVM堆內(nèi)存介紹
工欲善其事,必先利其器柱查。所以了解堆內(nèi)存的內(nèi)部結(jié)構(gòu)是很必要的廓俭。
在JVM中堆空間劃分為三個代:年輕代(Young Generation)、年老代(Old Generation)和永久代(Permanent Generation)物赶。年輕帶主要是動態(tài)的存儲白指,年輕帶主要儲存新產(chǎn)生的對象,年老代儲存年齡大些的對象酵紫,永久帶主要是存儲的是java的類信息告嘲,包括解析得到的方法错维、屬性、字段等橄唬。永久帶基本不參與垃圾回收赋焕。所以說我們說的垃圾回收主要是針對年輕代和年老代。
年輕代又分成3個部分仰楚,一個eden區(qū)和兩個相同的survior區(qū)隆判。剛開始創(chuàng)建的對象都是放置在eden區(qū)的。分成這樣3個部分僧界,主要是為了生命周期短的對象盡量留在年輕帶侨嘀。當eden區(qū)申請不到空間的時候,進行minorGC捂襟,把存活的對象拷貝到survior咬腕。年老代主要存放生命周期比較長的對象,比如緩存對象葬荷。(經(jīng)過IBM的一個研究機構(gòu)研究數(shù)據(jù)表明涨共,基本上80%-98%的對象都會在年輕代的Eden區(qū)死掉從而本回收掉,所以說真正進入到老年代的對象很少宠漩,這也是為什么MinorGC比MajorGC更加頻繁的原因)
具體JVM內(nèi)存垃圾回收過程描述如下 :
1举反、對象在Eden區(qū)完成內(nèi)存分配
2、當Eden區(qū)滿了扒吁,再創(chuàng)建對象火鼻,會因為申請不到空間,觸發(fā)minorGC瘦陈,進行young(eden+1survivor)區(qū)的垃圾回收
3凝危、minorGC時,Eden不能被回收的對象被放入到空的survivor(Eden肯定會被清空)晨逝,另一個survivor里不能被GC回收的對象也會被放入這個survivor,始終保證一個survivor是空的
4懦铺、當做第3步的時候捉貌,如果發(fā)現(xiàn)survivor滿了,則這些對象被copy到old區(qū)冬念,或者survivor并沒有滿趁窃,但是有些對象已經(jīng)足夠Old,也被放入Old區(qū) XX:MaxTenuringThreshold
5急前、當Old區(qū)被放滿的之后醒陆,進行fullGC
補充:
MinorGC:年輕代所進行的垃圾回收,非常頻繁裆针,一般回收速度也比較快刨摩。
MajorGC:老年代進行的垃圾回收寺晌,發(fā)生一次MajorGC至少伴隨一次MinorGC,一般比MinorGC速度慢十倍以上澡刹。
FullGC:整個堆內(nèi)存進行的垃圾回收呻征,很多時候是MajorGC
以后就是堆內(nèi)存結(jié)構(gòu)已經(jīng)大致的垃圾回收過程。
二罢浇、對象分配原則
1.對象優(yōu)先分配在Eden區(qū)陆赋,如果Eden區(qū)沒有足夠的空間時,虛擬機執(zhí)行一次Minor GC嚷闭。
2.大對象直接進入老年代(大對象是指需要大量連續(xù)內(nèi)存空間的對象)攒岛。這樣做的目的是避免在Eden區(qū)和兩個Survivor區(qū)之間發(fā)生大量的內(nèi)存拷貝(新生代采用復(fù)制算法收集內(nèi)存)。
3.長期存活的對象進入老年代胞锰。虛擬機為每個對象定義了一個年齡計數(shù)器灾锯,如果對象經(jīng)過了1次Minor GC那么對象會進入Survivor區(qū),之后每經(jīng)過一次Minor GC那么對象的年齡加1胜蛉,知道達到閥值對象進入老年區(qū)挠进。
4.動態(tài)判斷對象的年齡。如果Survivor區(qū)中相同年齡的所有對象大小的總和大于Survivor空間的一半誊册,年齡大于或等于該年齡的對象可以直接進入老年代领突。
5.空間分配擔保。每次進行Minor GC時案怯,JVM會計算Survivor區(qū)移至老年區(qū)的對象的平均大小君旦,如果這個值大于老年區(qū)的剩余值大小則進行一次Full GC,如果小于檢查HandlePromotionFailure設(shè)置嘲碱,如果true則只進行Monitor GC,如果false則進行Full GC金砍。
三、垃圾收集器
作為JVM中的核心之一垃圾收集器麦锯,主要完成的功能包括:(1)發(fā)現(xiàn)無用信息對象恕稠;(2)回收被無用對象占用的內(nèi)存空間,使該空間可被程序再次使用扶欣。所以說我們在實現(xiàn)垃圾收集器的同時就要實現(xiàn)兩個算法一個是發(fā)現(xiàn)無用的對象第二就是回收該對象的內(nèi)存鹅巍。
收集器主要分為引用計數(shù)器和跟蹤收集器兩種,Sun JDK中采用跟蹤收集器作為GC實現(xiàn)策略料祠。發(fā)現(xiàn)無用對象只要的實現(xiàn)算法包括引用計數(shù)法和根搜索算法骆捧,引用計數(shù)法主要是JVM的早期實現(xiàn)方法,因為引用計數(shù)無法解決循環(huán)引用的問題髓绽,所以現(xiàn)在JVM實現(xiàn)的主要是根搜索算法敛苇,
引用計數(shù)法:堆中的每個對象對應(yīng)一個引用計數(shù)器。當每一次創(chuàng)建一個對象并賦給一個變量時顺呕,引用計數(shù)器置為1枫攀。當對象被賦給任意變量時括饶,引用計數(shù)器每次加1當對象出了作用域后(該對象丟棄不再使用),引用計數(shù)器減1脓豪,一旦引用計數(shù)器為0巷帝,對象就不可用從而可以被回收。 根搜索算法:通過一系列的名為“GC Roots”的對象作為起始點扫夜,從這些節(jié)點開始向下搜索楞泼,搜索所走過的路徑稱為引用鏈(Reference Chain),當一個對象到GC Roots沒有任何引用鏈相連(用圖論的話來說就是從GC Roots到這個對象不可達)時笤闯,則證明此對象是不可用的堕阔。
目前的收集器主要有三種:
串行收集器:使用單線程處理所有垃圾回收工作,因為無需多線程交互颗味,所以效率比較高
并行收集器:對年輕代進行并行垃圾回收超陆,因此可以減少垃圾回收時間。一般在多線程多處理器機器上使用
并發(fā)收集器:可以保證大部分工作都并發(fā)進行(應(yīng)用不停止)浦马,垃圾回收只暫停很少的時間时呀,此收集器適合對響應(yīng)時間要求比較高的中、大規(guī)模應(yīng)用
四晶默、垃圾收集器的回收算法
Copying算法:
算法:復(fù)制采用的方式為從根集合掃描出存活的對象谨娜,并將找到的存活對象復(fù)制到一塊新的完全未使用的空間中。
過程: 此算法把內(nèi)存空間劃為兩個相等的區(qū)域磺陡,每次只使用其中一個區(qū)域趴梢。垃圾回收時,遍歷當前使用區(qū)域币他,把正在使用中的對象復(fù)制到另外一個區(qū)域中坞靶。次算法每次只處理正在使用中的對象,因此復(fù)制成本比較小蝴悉,同時復(fù)制過去以后還能進行相應(yīng)的內(nèi)存整理彰阴,不過出現(xiàn)“碎片”問題。當然拍冠,此算法的缺點也是很明顯的硝枉,就是需要兩倍內(nèi)存空間。
Mark-Sweep算法:
算法:標記-清除采用的方式為從根集合開始掃描倦微,對存活的對象進行標記,標記完畢后正压,再掃描整個空間中未標記的對象欣福,并進行回收。
過程: 第一階段從引用根節(jié)點開始標記所有被引用的對象焦履,第二階段遍歷整個堆拓劝,把未標記的對象清除雏逾。它停止所有工作,收集器從根開始訪問每一個活躍的節(jié)點郑临,標記它所訪問的每一個節(jié)點栖博。走過所有引用后,收集就完成了厢洞,然后就對堆進行清除(即對堆中的每一個對象進行檢查)仇让,所有沒有標記的對象都作為垃圾回收并返回空閑列表。
Mark-Compact算法:
算法:標記階段與“Mark-Sweep”算法相同躺翻,但在清除階段有所不同丧叽。在回收不存活對象所占用的內(nèi)存空間后,會將其他所有存活對象都往左端空閑的空間進行移動公你,并更新引用其對象指針踊淳。
過程:此算法結(jié)合了“標記-清除”和“復(fù)制”兩個算法的優(yōu)點。也是分兩階段陕靠,第一階段從根節(jié)點開始標記所有被引用對象迂尝,第二階段遍歷整個堆,把清除未標記對象并且把存活對象“壓縮”到堆的其中一塊剪芥,按順序排放垄开。此算法避免了“標記-清除”的碎片問題,同時也避免了“復(fù)制”算法的空間問題粗俱。
Sun JDK GC策略:
新生代算法實現(xiàn):Copying,Copying,Copying
舊生代算發(fā)實現(xiàn):Mark-Sweep-Compact说榆,Mark –Compact,Mark –Sweep4缛稀签财!