JAVA虛擬機(jī)
垃圾回收主要是回收堆內(nèi)存语稠。在垃圾回收期(GC)回收之前蛤肌,需要確定哪些對(duì)象可以回收恩溅,有以下幾種方法:
引用計(jì)數(shù)算法?
原理:給對(duì)象添加一個(gè)引用計(jì)數(shù)器乓序,每當(dāng)有一個(gè)地方引用它時(shí)寺酪,計(jì)數(shù)器值就加1;當(dāng)引用失效時(shí)替劈,計(jì)數(shù)器值就減1寄雀;任何時(shí)刻計(jì)數(shù)器都為0的對(duì)象就是不可能再被使用的。這種算法效率高陨献。不過很難解決對(duì)象之間的相互循環(huán)引用的問題盒犹。
根搜索算法(默認(rèn))?
原理:通過一系列的名為“GC Roots”的對(duì)象作為起始點(diǎn),從這些節(jié)點(diǎn)開始向下搜索眨业,搜索所走過的路徑稱為引用鏈急膀,當(dāng)一個(gè)對(duì)象到GC Roots沒有任何引用鏈相連時(shí),則證明此對(duì)象是不可用的龄捡。作為GC Roots的對(duì)象包括以下幾種:
虛擬機(jī)棧中的引用的對(duì)象
方法區(qū)中的類靜態(tài)屬性引用的對(duì)象
方法區(qū)中的常量引用的對(duì)象
本地方法棧中JNI的引用的對(duì)象
引用
強(qiáng)引用卓嫂,類似"Object obj = new Object()"這種,只要強(qiáng)引用存在聘殖,則GC永遠(yuǎn)不會(huì)回收被引用的對(duì)象
軟引用晨雳,指還有用,但是并非必須的對(duì)象就斤,內(nèi)存溢出之前進(jìn)行回收悍募,實(shí)現(xiàn)軟引用可以通過SoftReference類,軟引用主要用戶實(shí)現(xiàn)類似緩存的功能洋机,在內(nèi)存足夠的情況下直接通過軟引用取值坠宴,無(wú)需從繁忙的真實(shí)來(lái)源查詢數(shù)據(jù),提升速度绷旗;當(dāng)內(nèi)存不足時(shí)喜鼓,自動(dòng)刪除這部分緩存數(shù)據(jù)副砍,從真正的來(lái)源查詢這些數(shù)據(jù)。
弱引用庄岖,跟軟引用一樣豁翎,不過強(qiáng)度比軟引用弱一些,第二次垃圾回收時(shí)回收隅忿,實(shí)現(xiàn)弱引用可以通過WeakReference類心剥,弱引用主要用于監(jiān)控對(duì)象是否已經(jīng)被垃圾回收器標(biāo)記為即將回收的垃圾,可以通過弱引用的isEnQueued方法返回對(duì)象是否被垃圾回收器標(biāo)記背桐。
虛引用优烧,是最弱的一種引用關(guān)系,垃圾回收時(shí)回收链峭,無(wú)法通過引用取到對(duì)象值畦娄。主要用于檢測(cè)對(duì)象是否已經(jīng)從內(nèi)存中刪除。
垃圾收集算法
標(biāo)記-清除算法:首先標(biāo)記出所有需要回收的對(duì)象弊仪,在標(biāo)記完成后統(tǒng)一回收所有被標(biāo)記的對(duì)象熙卡,不過該算法有以下缺點(diǎn):
效率低
空間問題,該算法會(huì)產(chǎn)生大量不連續(xù)的內(nèi)存碎片励饵,這樣導(dǎo)致程序在以后的運(yùn)行中如果需要分配較大對(duì)象時(shí)無(wú)法找到足夠的連續(xù)內(nèi)存而觸發(fā)另一次垃圾收集動(dòng)作
復(fù)制算法:將可用內(nèi)存按容量劃分大小相等的兩塊驳癌,每次只使用其中的一塊。當(dāng)一塊內(nèi)存用完了曲横,就將還存活的對(duì)象復(fù)制到另外一塊上面喂柒,然后再把已使用過的內(nèi)存空間一次清理掉。這種算法實(shí)現(xiàn)簡(jiǎn)單禾嫉,效率高,不過會(huì)將可使用的內(nèi)存減少一半蚊丐。如果對(duì)象存活率高就要執(zhí)行較多的復(fù)制操作熙参,將導(dǎo)致效率變低。目前在復(fù)制算法中麦备,通常是將內(nèi)存分為一塊較大的Eden空間和兩塊較小的Survivor空間孽椰,每次只使用Eden和一塊Survivor。當(dāng)回收時(shí)凛篙,將Eden和Survivor中還存活的對(duì)象一次性拷貝到另外一塊Survivor中黍匾,最后清理使用的Eden和Survivor。并且以老年代作為空間分配擔(dān)保呛梆,即Survivor無(wú)法容納的對(duì)象會(huì)直接進(jìn)入老年代锐涯。目前新生代主要采用這個(gè)算法。
標(biāo)記-整理算法:將所有存活的對(duì)象都向一端移動(dòng)填物,然后直接清理掉邊界以外的內(nèi)存纹腌。
分代收集算法:根據(jù)對(duì)象的存活周期的不同將內(nèi)存劃分為幾塊霎终,一般是分為新生代和老年代。然后根據(jù)各個(gè)年代的特點(diǎn)采用最適當(dāng)?shù)氖占惴ㄉ怼P律ǔ2捎脧?fù)制算法莱褒,因?yàn)閷?duì)象生存時(shí)間都不長(zhǎng)。老年代一般采用"標(biāo)記-清理"或者"標(biāo)記-整理"算法回收涎劈,因?yàn)槔夏甏袑?duì)象存活率高广凸,沒有額外空間對(duì)它進(jìn)行分配擔(dān)保。