真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Java中怎么實(shí)現(xiàn)一個(gè)垃圾收集器

這期內(nèi)容當(dāng)中小編將會(huì)給大家?guī)?lái)有關(guān)Java中怎么實(shí)現(xiàn)一個(gè)垃圾收集器,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

創(chuàng)新互聯(lián)公司于2013年創(chuàng)立,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項(xiàng)目成都網(wǎng)站制作、成都網(wǎng)站設(shè)計(jì)、外貿(mào)營(yíng)銷網(wǎng)站建設(shè)網(wǎng)站策劃,項(xiàng)目實(shí)施與項(xiàng)目整合能力。我們以讓每一個(gè)夢(mèng)想脫穎而出為使命,1280元奉賢做網(wǎng)站,已為上家服務(wù),為奉賢各地企業(yè)和個(gè)人服務(wù),聯(lián)系電話:18982081108

 1、對(duì)象存活判定算法 :

1)引用記數(shù)算法:給每個(gè)對(duì)象添加一個(gè)引用計(jì)數(shù)器,每當(dāng)有一個(gè)地方引用,計(jì)數(shù)器就加1,當(dāng)引用失效時(shí)就減1,任何時(shí)刻計(jì)數(shù)器為0的對(duì)象就是不可能再被引用的。但是主流的Java虛擬機(jī)里面沒(méi)有選用引用計(jì)數(shù)器算法來(lái)管理內(nèi)存,其中最主要的原因是它很難解決對(duì)象之間相互循環(huán)引用的問(wèn)題。

2)可達(dá)性分析算法:通過(guò)一系列稱為“GC Roots”的對(duì)象作為起始點(diǎn),從這些節(jié)點(diǎn)向下搜索,搜索所走過(guò)的路徑稱為引用鏈,當(dāng)一個(gè)對(duì)象到GCRoots沒(méi)有任何引用鏈時(shí),則證明此對(duì)象是不可用的。主流實(shí)現(xiàn)。

在Java語(yǔ)言中,可作為GCRoots的對(duì)象包括下面幾種:a.虛擬機(jī)棧中引用的對(duì)象;b.方法區(qū)中類靜態(tài)屬性引用的對(duì)象;c.方法區(qū)中常量引用的對(duì)象;d.本地方法棧中JNI引用的對(duì)象。

2、生存還是死亡

真正宣告一個(gè)對(duì)象死亡,至少要經(jīng)歷兩次標(biāo)記過(guò)程:

1)可達(dá)性分析后發(fā)現(xiàn)不可達(dá),進(jìn)行第一次標(biāo)記,并將沒(méi)有必要執(zhí)行finalize方法的對(duì)象放到一個(gè)F-Queue隊(duì)列;

2)GC對(duì)F-Queue隊(duì)列中的對(duì)象進(jìn)行第二次小規(guī)模標(biāo)記,如果還是不可達(dá),基本就真的被回收了。

3、關(guān)于finalize方法

1)當(dāng)對(duì)象沒(méi)有覆蓋finalize方法,或者finalize方法已經(jīng)被虛擬機(jī)調(diào)用過(guò),虛擬機(jī)將這兩種情況都視為“沒(méi)有必要執(zhí)行”,所謂“執(zhí)行”是指虛擬機(jī)會(huì)觸發(fā)發(fā)這個(gè)方法,但并不承諾會(huì)等待它運(yùn)行結(jié)束;

2)finalize方法只會(huì)被系統(tǒng)調(diào)用一次;

3)finalize方法能做的所有工作,try-finally或者其它方式都可以做的更好、更及時(shí),所以建議完全可以忘掉Java語(yǔ)言中這個(gè)方法的存在。

4、垃圾收集算法:標(biāo)記-清理、復(fù)制、標(biāo)記-整理、分代收集

1)標(biāo)記-清理算法

a.分兩個(gè)階段:標(biāo)記和清理,首先標(biāo)記出需要回收的對(duì)象,在標(biāo)記完成后統(tǒng)一回收所有被標(biāo)記的對(duì)象;

b.不足:一個(gè)是效率問(wèn)題,標(biāo)記和清理兩個(gè)過(guò)程的效率不高;另一個(gè)是空間問(wèn)題,標(biāo)記清理后會(huì)產(chǎn)生大量不連續(xù)的內(nèi)存碎片,空間碎片太多可能會(huì)導(dǎo)致以后在程序運(yùn)行過(guò)程中需要分配較大對(duì)象時(shí),無(wú)法找到足夠的連續(xù)內(nèi)存而不得不提前觸發(fā)一次垃圾收集動(dòng)作。

2)復(fù)制算法

a.將可用內(nèi)存按容量劃分為大小相等的兩塊,每次只使用其中的一塊。當(dāng)一塊的內(nèi)存用完了,就將還存活的對(duì)象復(fù)制到另一塊上面,然后再把已使用的內(nèi)存空間一次清理掉。效率提高,也沒(méi)有內(nèi)存碎片的問(wèn)題。代價(jià)是內(nèi)存縮小為原來(lái)的一半。

b.新生代的對(duì)象98%是“朝生夕死”的,所以并不需要按照1:1的比例來(lái)劃分內(nèi)存空間,而是將內(nèi)存分為一塊較大的Eden空間和兩塊較小的Survivor空間,每次使用Eden和其中一塊Survivor。當(dāng)回收時(shí),將Eden和Survivor中還存活的對(duì)象一次性復(fù)制到另外一塊Survivor空間上,最后清理掉Eden和剛才用過(guò)的Survivor空間。HotSpot虛擬機(jī)默認(rèn)Eden和Survivor的大小比例是8:1,也就是每次新生代中可用內(nèi)存空間為整個(gè)新生代容量的90%,只有10%的內(nèi)存會(huì)被“浪費(fèi)”。如果另外一塊Survivor空間沒(méi)有足夠的空間存放上一次新生代收集下來(lái)的存活對(duì)象時(shí),這些對(duì)象將直接通過(guò)分配擔(dān)保機(jī)制進(jìn)入老年代。

3)標(biāo)記-整理算法

a.分兩個(gè)階段:標(biāo)記和整理,首先標(biāo)記出需要回收的對(duì)象,然后讓存活的對(duì)象都往一端移動(dòng),然后直接清理掉邊界以外的內(nèi)存。

4)分代收集算法

a.一般把Java堆分成新生代和老年代,這樣就可以根據(jù)各個(gè)年代的特點(diǎn)采用最適當(dāng)?shù)氖占惴āT谛律?,每次垃圾收集時(shí)都發(fā)現(xiàn)有大批對(duì)象死去,只有少量存活,那就選用復(fù)制算法,只需要付出少量存活對(duì)象的復(fù)制成本就可以完成收集。而老年代中因?yàn)閷?duì)象存活率高、沒(méi)有額外空間對(duì)它進(jìn)行分配擔(dān)保,就必須使用“標(biāo)記-清理”或者“標(biāo)記-整理”算法來(lái)進(jìn)行回收。

5、HotSpot的算法實(shí)現(xiàn)

1)枚舉根結(jié)點(diǎn):由于目前的主流Java虛擬機(jī)使用的都是準(zhǔn)確式GC,所以當(dāng)執(zhí)行系統(tǒng)停頓下來(lái)后,并不需要一個(gè)不漏的檢查完所有執(zhí)行上下文和全局的引用位置,虛擬機(jī)應(yīng)當(dāng)有辦法直接得知哪些地方存放著對(duì)象引用。在HotSpot的實(shí)現(xiàn)中,使用一組成為OopMap的數(shù)據(jù)結(jié)構(gòu)來(lái)記錄對(duì)象引用。

2)安全點(diǎn):程序在執(zhí)行時(shí)并非所有的地方都能停頓下來(lái)開(kāi)始GC,只有在到達(dá)安全點(diǎn)時(shí)才能暫停。安全點(diǎn)的選定既不能太少以致于讓GC等待時(shí)間太常,也不能太頻繁以致于過(guò)分增大運(yùn)行時(shí)負(fù)荷。所以安全點(diǎn)的選定基本上是以程序“是否具有讓程序長(zhǎng)時(shí)間執(zhí)行的特征”為標(biāo)準(zhǔn)進(jìn)行選定的?!伴L(zhǎng)時(shí)間執(zhí)行”最明顯的特征就是指令序列復(fù)用,例如方法調(diào)用、循環(huán)跳轉(zhuǎn)、異常跳轉(zhuǎn)等,所以具有這些功能的指令才會(huì)產(chǎn)生安全點(diǎn)。另外一個(gè)需要考慮的問(wèn)題時(shí)如何在GC發(fā)生時(shí)讓所有線程“跑”到最近的安全點(diǎn)上再停頓下來(lái)。這里有兩個(gè)方案:搶占式中斷和主動(dòng)式中斷?,F(xiàn)在幾乎沒(méi)有虛擬機(jī)實(shí)現(xiàn)采用搶占式中斷來(lái)暫停線程從而相應(yīng)GC事件。而主動(dòng)式中斷的思想時(shí)當(dāng)GC需要中斷線程的時(shí)候,不直接對(duì)線程操作,僅僅簡(jiǎn)單地設(shè)置一個(gè)標(biāo)志,各個(gè)線程執(zhí)行時(shí)主動(dòng)去輪詢這個(gè)標(biāo)志,發(fā)現(xiàn)中斷標(biāo)志為真時(shí)就中斷掛起,輪詢標(biāo)志的地方和安全點(diǎn)是重合的,另外再加上創(chuàng)建對(duì)象需要分配內(nèi)存的地方。

3、安全區(qū)域:指在一段代碼片段之中,引用關(guān)系不會(huì)發(fā)生變化。在這個(gè)區(qū)域中的任意地方開(kāi)始GC都是安全的。在線程執(zhí)行到安全區(qū)域中的代碼時(shí),首先標(biāo)識(shí)自己已經(jīng)進(jìn)入安全區(qū)域,那樣,當(dāng)在這段時(shí)間里JVM要發(fā)起GC時(shí),就不用管標(biāo)識(shí)自己為安全區(qū)域狀態(tài)的線程了。在線程要離開(kāi)安全區(qū)域時(shí),它要檢查系統(tǒng)是否已經(jīng)完成根結(jié)點(diǎn)枚舉,如果完成了,那線程就繼續(xù)執(zhí)行,否則它就必須等待直到收到可以安全離開(kāi)安全區(qū)域的信號(hào)為止。 

6、垃圾收集器:a.新生代收集器:Serial、Parnew、Parallel Scavenge,b.老年代收集器:Parallel Old、CMS、Serial Old,c.G1。

1)Serial收集器:?jiǎn)尉€程收集器,在它進(jìn)行垃圾回收時(shí),必須暫停其他所有的工作線程,直到它收集結(jié)束;

2)ParNew收集器:Serial收集器的多線程版本,除Serial收集器外,目前只有它能與CMS收集器配合工作;

3)Parallel Scavenge收集器:目標(biāo)時(shí)達(dá)到一個(gè)可控制的吞吐量,也稱“吞吐量?jī)?yōu)先”收集器;

4)Serial Old收集器:Serial收集器的老年代版本,同樣是一個(gè)單線程收集器,使用“標(biāo)記-整理”算法;

5)Parallel Old收集器:Parallel Scavenge收集器的老年代版本,使用多線程和“標(biāo)記-整理”算法,在注重吞吐量以及CPU資源敏感的場(chǎng)合,都可以優(yōu)先考慮Parallel Scavenge + Parallel Old收集器。

6)CMS收集器:以獲取最短回收停頓時(shí)間為目標(biāo)的收集器,基于“標(biāo)記-清理”算法實(shí)現(xiàn)的。優(yōu)點(diǎn)是:并發(fā)收集、低停頓。

7)G1收集器:它將整個(gè)Java堆劃分為多個(gè)大小相等的獨(dú)立區(qū)域,能夠建立可預(yù)測(cè)的停頓時(shí)間模型。G1跟蹤各個(gè)Region里面的垃圾堆積的價(jià)值大小,在后臺(tái)維護(hù)一個(gè)優(yōu)先列表,每次根據(jù)允許的收集時(shí)間,優(yōu)先回收價(jià)值最大的Region。

7、GC日志:每種收集器的日至不一樣,但都有共性,以下是典型的GC日志

1)33.125: [GC [DefNew: 3324K->152K(3712K), 0.0025925 secs] 3324K->152K(11904K), 0.0031680 secs]

2)100.667: [Full GC [Tenured: 0K->210K(10240K), 0.0149142 secs] 4603K->210K(19456K), [Perm: 2999K->2999K(21248K)], 0.015007 secs] [Times: user=0.01 sys=0.00, real=0.02 secs]

a.最開(kāi)始的數(shù)字代表GC發(fā)生的時(shí)間,這個(gè)數(shù)字的含義是從Java虛擬機(jī)啟動(dòng)以來(lái)經(jīng)過(guò)的秒數(shù);

b.[GC 和[Full GC說(shuō)明了這次垃圾收集的停頓類型,而不是來(lái)區(qū)分新生代GC和老年代GC的。Full,說(shuō)明這次GC發(fā)生了一次Stop-The-World。

c.[DefNew 、[Tenured、[Perm表示GC發(fā)生的區(qū)域,不同的垃圾收集器顯示的名稱不同

d.后面方括號(hào)內(nèi)部3324->152K(3712)表示“GC前該內(nèi)存區(qū)域已使用容量->GC后該內(nèi)存區(qū)域已使用容量(該內(nèi)存區(qū)域總?cè)萘?”

e.方括號(hào)之外的3324->152K(11904K)表示“GC前Java堆已使用容量->GC后Java堆已使用容量(Java堆總?cè)萘?”

f.再往后,0.0025925 secs表示該內(nèi)存區(qū)域GC所占用的時(shí)間,單位是秒,有的收集器會(huì)給出更具體的時(shí)間,user、sys、real分別表示用戶態(tài)消耗的CPU時(shí)間、內(nèi)核態(tài)消耗的CPU時(shí)間和操作從開(kāi)始到結(jié)束所經(jīng)過(guò)的墻鐘時(shí)間(Wall Clock Time)。CPU時(shí)間與墻鐘時(shí)間的區(qū)別是,墻鐘時(shí)間包括各種非運(yùn)算的等待耗時(shí)。

8、內(nèi)存分配規(guī)則:以下是幾條最普遍的內(nèi)存分配規(guī)則

1)對(duì)象優(yōu)先在Eden分配;

2)大對(duì)象直接進(jìn)入老年代:所謂大對(duì)象是指需要大量連續(xù)內(nèi)存空間Java對(duì)象,最典型的大對(duì)象就是那種很長(zhǎng)的字符串以及數(shù)組,避免短命大對(duì)象;

3)長(zhǎng)期存活的對(duì)象直接進(jìn)入老年代:虛擬機(jī)給每個(gè)對(duì)象定義了一個(gè)對(duì)象年齡計(jì)數(shù)器,每次MinorGC后仍然存活,并且能被Survivor容納的話,對(duì)象年齡加1,當(dāng)它的年齡到達(dá)一定程度(默認(rèn)15歲),就會(huì)晉升到老年代。

4)動(dòng)態(tài)對(duì)象年齡判定:虛擬機(jī)不是必須要求對(duì)象的年齡必須達(dá)到MaxTenuringThreshold才能晉升老年代,如果Survivor空間中相同年齡所有對(duì)象大小總和大于Survivor空間的一半,年齡大于或等于該年齡的對(duì)象就可以直接進(jìn)入老年代。

9、空間分配擔(dān)保

在發(fā)生MinorGC之前,虛擬機(jī)會(huì)先檢查老年代最大可用的連續(xù)空間是否大于新生代所有對(duì)象總空間,如果這個(gè)條件成立,那么MinorGC可以確保是安全的,如果不成立,則虛擬機(jī)會(huì)查看HandlePromotionFailure設(shè)置值是否允許擔(dān)保失敗,如果允許,那么會(huì)繼續(xù)檢查老年代最大可用的連續(xù)空間是否大于歷次晉升到老年代對(duì)象的平均大小,如果大于,將嘗試進(jìn)行一次MinorGC,盡管這次MinorGC是有風(fēng)險(xiǎn)的,如果小于或者HandlePromotionFailure設(shè)置不允許冒險(xiǎn),那這時(shí)也要改為進(jìn)行一次FullGC。

上述就是小編為大家分享的Java中怎么實(shí)現(xiàn)一個(gè)垃圾收集器了,如果剛好有類似的疑惑,不妨參照上述分析進(jìn)行理解。如果想知道更多相關(guān)知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。


分享題目:Java中怎么實(shí)現(xiàn)一個(gè)垃圾收集器
網(wǎng)站鏈接:http://weahome.cn/article/gdohih.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部