一、判斷對(duì)象回收
1士修、判斷方法
引用計(jì)數(shù)算法:對(duì)象每次引用枷遂,引用計(jì)數(shù)加1,取消引用減一棋嘲,當(dāng)引用計(jì)數(shù)為0酒唉,則判斷對(duì)象可回收,但是難以處理兩個(gè)對(duì)象的互相引用的問(wèn)題沸移。
可達(dá)性分析算法:通過(guò)一系列的稱(chēng)為GC Roots的對(duì)象作為起點(diǎn)痪伦,從這些節(jié)點(diǎn)往下搜索,搜索所走過(guò)的路徑稱(chēng)為引用鏈雹锣,當(dāng)一個(gè)對(duì)象到達(dá)GC Roots沒(méi)有任何引用鏈相連网沾,則此對(duì)象不可用。
可作為GC Root的對(duì)象有如下幾種:
?1蕊爵、虛擬機(jī)棧中引用的對(duì)象辉哥。
? 2、方法區(qū)中類(lèi)靜態(tài)屬性引用的對(duì)象攒射。
?3醋旦、方法區(qū)中常量引用的對(duì)象。
2匆篓、Java引用分類(lèi)
?強(qiáng)引用:只要強(qiáng)引用還在浑度,垃圾收集器永遠(yuǎn)不會(huì)回收掉引用對(duì)象。
?軟引用:內(nèi)存發(fā)生溢出之前鸦概,會(huì)把這些對(duì)象回收箩张。
?弱引用:不管內(nèi)存是否足夠,垃圾收集器工作時(shí)窗市,會(huì)回收掉這些對(duì)象先慷。
?虛引用:無(wú)法通過(guò)虛引用獲取對(duì)象實(shí)例。
3咨察、生存還是死亡
? 可達(dá)性分析算法中不可達(dá)的對(duì)象论熙,也并非非死不可,它們暫時(shí)處于緩刑階段摄狱,真正的死亡脓诡,還是要經(jīng)過(guò)兩次標(biāo)記篩選无午,第一次,篩選的標(biāo)準(zhǔn)祝谚,對(duì)象是否有必要執(zhí)行finalize方法宪迟,當(dāng)對(duì)象沒(méi)有覆蓋finalize方法,或者已經(jīng)執(zhí)行過(guò)交惯,則執(zhí)行對(duì)象回收次泽,對(duì)象被判定有必要執(zhí)行finalize方法,則會(huì)把對(duì)象放入隊(duì)列中席爽,虛擬機(jī)機(jī)則會(huì)在開(kāi)啟低優(yōu)先機(jī)線程去執(zhí)行它意荤,稍后GC將對(duì)隊(duì)列中對(duì)象進(jìn)行第二次標(biāo)記。
4只锻、方法區(qū)(永久帶)的垃圾回收
? ?方法區(qū)進(jìn)行垃圾回收性?xún)r(jià)比比較低玖像,回收主要分為兩部分:廢棄的常量和無(wú)用的類(lèi)。
二炬藤、垃圾回收算法
?標(biāo)記清除算法
分為標(biāo)記和清除兩個(gè)階段御铃,缺點(diǎn):標(biāo)記和清除的效率都不高;另一個(gè)就是空間問(wèn)題沈矿,標(biāo)記清除后產(chǎn)生大量的內(nèi)存碎片,內(nèi)存碎片可能導(dǎo)致咬腋,下次分配較大對(duì)象時(shí)羹膳,無(wú)法獲取到足夠大的內(nèi)存地址,而出發(fā)GC操作根竿。
復(fù)制算法
將內(nèi)存分為大小相等的兩塊陵像,每次使用一塊,當(dāng)這塊使用完了寇壳,就將活著的對(duì)象復(fù)制到另一塊醒颖,然后一次清除掉使用的那塊,這種方式不存在內(nèi)存碎片的問(wèn)題壳炎,但是內(nèi)存的使用效率卻降低了泞歉。新生代垃圾回收才用次回收算法,Eden和兩塊Survivor區(qū)間分配比例:8:1:1匿辩,每次使用Eden和其中一塊Survivor,當(dāng)回收時(shí)腰耙,將Eden和Survivor中活著的對(duì)象復(fù)制到另一塊Survivor中,如果另一塊Survivor大小不夠铲球,這些對(duì)象通過(guò)分配擔(dān)保進(jìn)入老年代挺庞。
?標(biāo)記整理算法
?將標(biāo)記好的對(duì)象,當(dāng)回收時(shí)稼病,所有存活的對(duì)象往一端移動(dòng)选侨,清除掉所有端邊界以外的空間掖鱼。
?分代收集算法
? 把Java堆分為新生代和老年代,新生代每次垃圾收集時(shí)有大批的對(duì)象死去援制,存活很少锨用,選用復(fù)制算法,老年代對(duì)象存活率高又不能進(jìn)行分配擔(dān)保隘谣,使用標(biāo)記清除或者標(biāo)記整理增拥。
? ? ? ? ?當(dāng)垃圾回收時(shí),所有的線程到達(dá)安全點(diǎn)寻歧,GC開(kāi)始垃圾回收掌栅,通過(guò)搶斷式中斷和主動(dòng)式中斷來(lái)保證到達(dá)安全點(diǎn)。搶斷式中斷:中斷所有的線程码泛,如果線程不在安全點(diǎn)猾封,就恢復(fù)線程,到達(dá)安全點(diǎn)噪珊;主動(dòng)式中斷晌缘,設(shè)置一個(gè)標(biāo)志,所有的線程都去輪訓(xùn)這個(gè)標(biāo)志痢站,當(dāng)標(biāo)志為真時(shí)磷箕,線程主動(dòng)掛起中斷。
安全區(qū)域:指一段代碼片段中阵难,引用關(guān)系不會(huì)發(fā)生變化岳枷,在這個(gè)區(qū)域,任何地方開(kāi)始GC都是安全的呜叫,線程執(zhí)行到安全區(qū)域空繁,首先標(biāo)識(shí)自己進(jìn)入安全區(qū)域,發(fā)生GC時(shí)朱庆,就不用管標(biāo)識(shí)安全區(qū)域的線程了盛泡。
二、垃圾收集器
?Serial:單線程收集器娱颊,工作時(shí)傲诵,停止所有的用戶工作線程。停頓時(shí)間長(zhǎng)维蒙。
?ParNew:Serial收集器的多線程版本掰吕,其他的和Serial一樣。
Parallel Scavenge:新生代收集器颅痊,并行多線程殖熟,特點(diǎn)達(dá)到一個(gè)可控制的吞吐量,吞吐量=代碼的運(yùn)行時(shí)間/(代碼運(yùn)行時(shí)間+垃圾收集的時(shí)間)
Serial Old:老年代斑响,單線程收集器菱属,可與ParNew Serial和 Serial 和?Parallel Scavenge 搭配使用钳榨。
? 采用標(biāo)記整理算法。
Parallel Old:老年代纽门,是Parallel Scavenge收集器的老年代收集器薛耻,多線程。
CMS收集器:以獲取最短停頓時(shí)間為目標(biāo)的收集器赏陵,重試服務(wù)的響應(yīng)速度饼齿,希望服務(wù)停頓的時(shí)間更短,可以考慮此收集器蝙搔,CMS收集器采用標(biāo)記清除算法缕溉,優(yōu)點(diǎn):并發(fā)收集,并發(fā)清除吃型。
缺點(diǎn):CMS默認(rèn)啟動(dòng)的線程數(shù)是(CPU數(shù)量+3)/4,當(dāng)CPU數(shù)量大于4時(shí)证鸥,并發(fā)回收時(shí)垃圾收集線程不少于25%的CPU資源,隨著CPU數(shù)量增加而下降勤晚,當(dāng)CPU少于2個(gè)的時(shí)候枉层,CMS對(duì)用戶線程的影響很大。
? CMS無(wú)法收集處理浮動(dòng)垃圾赐写,可能導(dǎo)致失敗而導(dǎo)致另一次Full GC的產(chǎn)生鸟蜡,并發(fā)的過(guò)程又會(huì)不斷產(chǎn)生新的垃圾。
?CMS標(biāo)記清除:會(huì)產(chǎn)生大量的碎片血淌,導(dǎo)致空間浪費(fèi)矩欠。
初始標(biāo)記:只標(biāo)記GCRoots能直接關(guān)聯(lián)到的對(duì)象,速度很快悠夯。
并發(fā)標(biāo)記:就是進(jìn)行GCRoots Tracing的過(guò)程。
重新標(biāo)記:為了修正并發(fā)標(biāo)記期間因用戶程序繼續(xù)運(yùn)作而導(dǎo)致標(biāo)記變動(dòng)的那一部分對(duì)象的標(biāo)記記錄躺坟。
并發(fā)清除:可以和用戶線程一起并發(fā)執(zhí)行沦补。
G!:收集器,并發(fā)并行咪橙,分代收集夕膀,空間整合,標(biāo)記-整理美侦,可預(yù)測(cè)的停頓产舞。
二、內(nèi)存分配與回收策略
?1菠剩、對(duì)象優(yōu)先在Eden分配:當(dāng)Eden沒(méi)有足夠的空間時(shí)易猫,進(jìn)行一次GC,如果還沒(méi)夠分配具壮,則通過(guò)分配擔(dān)保進(jìn)入老年代准颓。
2哈蝇、大對(duì)象直接進(jìn)入老年代:大對(duì)象是指那些需要大量連續(xù)內(nèi)存空間的Java對(duì)象,比如那些很長(zhǎng)的字符串和數(shù)組攘已。
3炮赦、長(zhǎng)期存活的對(duì)象進(jìn)入老年代:
4、動(dòng)態(tài)年齡判定:如果在Survivor空間中相同年齡的所有對(duì)象大小的和大于Survivor總空間的一半样勃,年齡大于或者等于該年齡的對(duì)象直接進(jìn)入老年代吠勘。
5、分配擔(dān)保:
?