歡迎掃碼關(guān)注我 ??
判斷對(duì)象是否存活
一哥童、引用計(jì)數(shù)算法
? 給對(duì)象中添加一個(gè)引用計(jì)數(shù)器递宅,每當(dāng)有一個(gè)地方引用他時(shí)就給計(jì)數(shù)器值加一歪泳;當(dāng)引用失效時(shí)任斋,計(jì)數(shù)器值就減一继阻;任何時(shí)刻計(jì)數(shù)器為0的對(duì)象就是不可能再被使用的。
? 缺點(diǎn):很難解決對(duì)象之間互相循環(huán)引用的問題废酷。
二瘟檩、可達(dá)性分析算法
? 以“GC Root”對(duì)象為起始點(diǎn),從此節(jié)點(diǎn)向下搜索澈蟆,搜索所走的路徑成為引用鏈墨辛,當(dāng)一個(gè)對(duì)象和GC Root之間沒有任何引用鏈的時(shí)候,則此對(duì)象為不可用對(duì)象趴俘。
如上圖所示睹簇,Object1到Object4與GC Root之間存在引用鏈,所以O(shè)bject1到Object4的對(duì)象是可達(dá)對(duì)象寥闪,而Object5和Object6沒有雨GC Root相關(guān)的引用鏈太惠,所以O(shè)bject5和Object6是不可達(dá)對(duì)象,是可以回收的對(duì)象疲憋。
? Java中可以被稱為GC Root的對(duì)象有以下幾種:
虛擬機(jī)棧中引用的對(duì)象
方法區(qū)中類靜態(tài)屬性引用的對(duì)象
方法區(qū)中常量引用的對(duì)象
本地方法棧中JNI(Native方法)引用的對(duì)象
三凿渊、四種引用類型
強(qiáng)引用:類似于new一個(gè)對(duì)象的引用,只要強(qiáng)引用存在柜某,垃圾收集器永遠(yuǎn)不會(huì)回收掉被引用的對(duì)象嗽元。
軟引用:描述的是一些還有用但并非必須的對(duì)象,對(duì)于軟引用關(guān)聯(lián)的對(duì)象喂击,在系統(tǒng)將要發(fā)生內(nèi)存溢出之前剂癌,會(huì)把這些對(duì)象列進(jìn)回收范圍之中進(jìn)行第二次回收,如果這次回收還沒有足夠的內(nèi)存就會(huì)拋出內(nèi)存溢出異常翰绊。
弱引用:描述非必須對(duì)象佩谷,被弱引用關(guān)聯(lián)的對(duì)象只能生存到下一次垃圾收集發(fā)生之前旁壮。當(dāng)垃圾收集器工作時(shí),無論當(dāng)前內(nèi)存是否足夠谐檀,都會(huì)回收只被弱引用關(guān)聯(lián)的對(duì)象抡谐。
虛引用:一個(gè)對(duì)象是否有虛引用存在,完全不會(huì)對(duì)其生存時(shí)間構(gòu)成影響桐猬,也無法通過虛引用來取得一個(gè)對(duì)象實(shí)例麦撵。為一個(gè)對(duì)象設(shè)置虛引用關(guān)聯(lián)的唯一目的就是當(dāng)這個(gè)對(duì)象被收集器收集時(shí)會(huì)收到一個(gè)系統(tǒng)通知。
如果一個(gè)對(duì)象在可達(dá)性分析時(shí)沒后沒有與GC Root相連接的引用鏈溃肪,它將會(huì)第一次標(biāo)記并篩選免胃,篩選條件是該對(duì)象是否有必要執(zhí)行finalize()方法,如果有必要執(zhí)行finalize()方法惫撰,對(duì)象只要重新與引用鏈上的任何一個(gè)對(duì)象建立關(guān)聯(lián)即可羔沙,拿在第二次標(biāo)記時(shí)將他移除“即將回收”集合。任何對(duì)象的finalize()方法只會(huì)被調(diào)用一次厨钻,如果對(duì)象面臨下一次回收扼雏,它的finalize()方法不會(huì)被再次執(zhí)行。
垃圾收集算法
一夯膀、標(biāo)記—清除算法
? 首先標(biāo)記出所有要回收的對(duì)象诗充,在標(biāo)記完成后統(tǒng)一回收被標(biāo)記的對(duì)象。
? 缺點(diǎn):1棍郎、效率問題其障,標(biāo)記和清除兩個(gè)過程的效率都不高。
2涂佃、空間問題励翼,標(biāo)記清除會(huì)產(chǎn)生大量不連續(xù)的內(nèi)存碎片,空間碎片太多會(huì)導(dǎo)致以后程序運(yùn)行過程中需要分配較大對(duì)象時(shí)辜荠,無法找到足夠的連續(xù)內(nèi)存而不得進(jìn)行另一次垃圾收集動(dòng)作汽抚。
二、復(fù)制算法
? 將內(nèi)存安容量分為大小相等的兩塊伯病,每次只使用其中一塊造烁,當(dāng)著一塊內(nèi)存用完后,將存活的對(duì)象復(fù)制到另一塊上面午笛,再把已使用的內(nèi)存清理掉惭蟋。
? 一般虛擬機(jī)是將內(nèi)存分為一塊較大的Eden空間和兩塊較小的Survivor空間。每次使用药磺?Eden和其中一塊Survivor告组,回收時(shí),將Eden和Survivor還存后的對(duì)象復(fù)制到Survivor空間癌佩,再清理掉剛才用到的Survivor和Eden空間木缝。當(dāng)Survivor內(nèi)存不足時(shí)會(huì)用到其他內(nèi)存(老年代)進(jìn)行分配擔(dān)保便锨。
? 缺點(diǎn):在對(duì)象存活率較高時(shí)就要進(jìn)行較多的復(fù)制操作,效率會(huì)變低我碟,老年代一般不能直接選用這種做法放案。
三、標(biāo)記—整理算法
? 標(biāo)記過程與標(biāo)記—清除算法相同矫俺,然后讓所有存活的對(duì)象都像一端移動(dòng)吱殉,然后直接清理掉端邊界以外的內(nèi)存。適用于老年代整理恳守。
四考婴、分代收集算法
? 一般根據(jù)對(duì)象存活周期將對(duì)象劃分為幾塊贩虾。Java堆分為新生代和老年代催烘。新生代一般采用復(fù)制算法,而老年代對(duì)象存活較高缎罢,沒有額外空間對(duì)它進(jìn)行分配擔(dān)保伊群,就必須使用標(biāo)記—清除或標(biāo)記—整理算法。
垃圾收集器
一策精、Serial收集器
? 是虛擬機(jī)在client模式下默認(rèn)的新生代收集器舰始,是單線程收集器,必須停掉其他所有工作線程咽袜,知道他收集結(jié)束丸卷。
二、ParNew收集器
? 時(shí)Serial收集器的多線程版本询刹。是許多運(yùn)行在server模式下的虛擬機(jī)的首選的新生代收集器谜嫉。除了Serial收集器外,只有它能與CMS收集器配合工作凹联。
三沐兰、Parallel Scavenge收集器
? 并行多線程的新生代收集器。CMS等收集器的特點(diǎn)是盡可能縮短垃圾收集時(shí)用戶線程的停頓時(shí)間蔽挠,而Parallel Scavenge收集器的目的是達(dá)到一個(gè)可控制吞吐量住闯。吞吐量是指CPU用于運(yùn)行用戶代碼的時(shí)間與CPU總消耗的時(shí)間的比值
四、Serial Old收集器
? 是Serial收集器的老年代版本澳淑,單線程收集器比原。主要是給client模式下的虛擬機(jī)使用。在server模式下:一是可以與Parallel Scavenge收集器配合使用杠巡。另一方面是作為CMS收集器的后備方案量窘。
五、Parallel Old收集器
? 是Parallel Scavenge收集器的老年代版本忽孽,使用多線程和標(biāo)記—整理算法绑改。
六谢床、CMS收集器
? 是一種以獲取最短回收時(shí)間為目標(biāo)的收集器±逑撸基于標(biāo)記—清除算法實(shí)現(xiàn)识腿。運(yùn)作過程:
- 初始標(biāo)記
- 并發(fā)標(biāo)記
- 重新標(biāo)記
- 并發(fā)清除
其中初始標(biāo)記和重新標(biāo)記需要“stop the world”,并發(fā)標(biāo)記和并發(fā)清除是和用戶線程一起進(jìn)行的造壮。
缺點(diǎn):1渡讼、對(duì)CPU資源敏感,因?yàn)檎加昧艘徊糠志€程而導(dǎo)致應(yīng)用程序變慢耳璧,總吞吐量會(huì)降低成箫。
? 2、收集器無法處理浮動(dòng)垃圾旨枯。
? 3.采用標(biāo)記—清除算法會(huì)產(chǎn)生大量空間碎片蹬昌。
七、G1收集器
? 面向服務(wù)端應(yīng)用的垃圾收集器攀隔。優(yōu)點(diǎn)如下:
并行并發(fā)
分代收集
空間整合
可預(yù)測(cè)停頓
它將整個(gè)Java堆分為多個(gè)大小相等的獨(dú)立區(qū)域皂贩,保留新生代和老年代概念,但他們不是物理隔離昆汹,都是一部分Region的集合明刷。G1跟蹤各個(gè)Region里面的垃圾堆積的價(jià)值大小,在后臺(tái)維護(hù)一個(gè)優(yōu)先列表满粗,每次根據(jù)允許的手機(jī)時(shí)間辈末,優(yōu)先回收價(jià)值大的Region。
G1的操作步驟:
- 初始標(biāo)記
- 并發(fā)標(biāo)記
- 最終標(biāo)記
- 篩選回收
內(nèi)存分配與回收策略
一映皆、對(duì)象優(yōu)先在Eden分配
二挤聘、大對(duì)象直接進(jìn)入老年代
? 需要大量連續(xù)的內(nèi)存空間的Java對(duì)象,最典型就是很長(zhǎng)的字符串以及數(shù)組劫扒。
三檬洞、長(zhǎng)期存活的對(duì)象進(jìn)入老年代
? 虛擬機(jī)給每一個(gè)對(duì)象定義年齡計(jì)數(shù)器,在Eden代出生并經(jīng)過一次Minor GC仍存后沟饥,并能被Survivor接收添怔,被移到Survivor空間中,年齡加一贤旷。在Survivor中每熬過一次GC广料,年齡就加一。當(dāng)年齡到一定長(zhǎng)度后就進(jìn)入老年代幼驶。
四艾杏、動(dòng)態(tài)對(duì)象年齡判斷
? 如果在Survivor中的相同年齡所有對(duì)象大小的總和大于Survivor空間的一半,年齡大于等于改年齡的對(duì)象就會(huì)進(jìn)入老年代盅藻。
五购桑、空間分配擔(dān)保
? 在Minor GC前虛擬機(jī)會(huì)先檢查老年代最大可用的連續(xù)空間是否大于新生代所有對(duì)象的總空間畅铭,如果條件成立,那么Minor GC可以確保安全勃蜘。否則虛擬機(jī)會(huì)查看HandelPromotionFailure設(shè)置的值是否允許擔(dān)保失敗硕噩,如果是,則在檢查老年代最大可用的連續(xù)空間是否大于歷次晉升到老年代對(duì)象的平均大小缭贡,如果大于炉擅,嘗試進(jìn)行一次Minor GC。否則進(jìn)行一次Full GC
歡迎關(guān)注公眾號(hào):