JVM的垃圾回收的算法
什么是垃圾
沒(méi)有引用指向的任何對(duì)象
一柳沙、標(biāo)記清除算法(Mark-Sweep)
標(biāo)記清除算法是最基礎(chǔ)的回收算法,該算法包括兩個(gè)階段:①標(biāo)記階段 ②清除階段
標(biāo)記階段:根據(jù)可達(dá)性分析算法找出需要回收的對(duì)象進(jìn)行標(biāo)記利诺。
清除階段:統(tǒng)一回收被標(biāo)記的對(duì)象.
該算法的優(yōu)點(diǎn)和不足:
優(yōu)點(diǎn):
1.一目了然的就是邏輯簡(jiǎn)單,之后的算法也是在此基礎(chǔ)上進(jìn)行優(yōu)化。
不足:
1.效率問(wèn)題:標(biāo)記和清理的效率都不高(第一次掃描標(biāo)記不可回收對(duì)象–根可達(dá)標(biāo)記為存活對(duì)象,第二遍清除沒(méi)有被標(biāo)記的對(duì)象)
2空間問(wèn)題:清除的時(shí)候规辱,只是將零散的存儲(chǔ)在內(nèi)存中的對(duì)象進(jìn)行回收绿鸣,沒(méi)有進(jìn)行整理疚沐,導(dǎo)致很多零散的,不完整的內(nèi)存區(qū)域潮模,如果想再存儲(chǔ)較大的對(duì)象時(shí)亮蛔,就會(huì)促使再次進(jìn)行一次回收。
二擎厢、復(fù)制算法(Copying)
復(fù)制算法是為了解決標(biāo)記清除算法效率不高而產(chǎn)生的究流。該算法的思路就是將內(nèi)存空間一分為二,一模一樣大小相等的內(nèi)存空間动遭。每次只使用其中一塊來(lái)存儲(chǔ)對(duì)象,當(dāng)這一塊內(nèi)存使用的差不多的時(shí)候厘惦,將這塊中還存活的對(duì)象復(fù)制到另一塊內(nèi)存中,然后將原來(lái)的已經(jīng)使用過(guò)的內(nèi)存完全清理掉宵蕉。
這種算法的優(yōu)點(diǎn)和不足:
優(yōu)點(diǎn):每次回收對(duì)一半的空間進(jìn)行回收,也不需要考慮內(nèi)存碎片化羡玛,不整合的問(wèn)題了。提升了回收效率稼稿。
不足:對(duì)內(nèi)存一分為二讳窟,始終對(duì)一半的內(nèi)存操作,浪費(fèi)了一半的內(nèi)存
三挪钓、標(biāo)記-整理算法(Mark-Compact)
標(biāo)記-整理算法采用標(biāo)記-清除算法一樣的標(biāo)記方式進(jìn)行對(duì)象的標(biāo)記,但在清除時(shí)不同碌上,在回收那些不存活的對(duì)象占用的空間后,將后面活著的對(duì)象依次向前移動(dòng)浦徊。將所有活著的對(duì)象都移動(dòng)成內(nèi)存空間中一段連續(xù)的區(qū)域,之后的連續(xù)區(qū)域都是可分配的沒(méi)有使用的內(nèi)存空間盔性。因此成本很高霞丧,但是解決了碎片化內(nèi)存的問(wèn)題。
四冕香、分代收集算法
分代收集算法是目前大部分JVM的垃圾收集器采用的算法蛹尝。其核心思想是根據(jù)對(duì)象存活的生命周期將內(nèi)存劃分為若干個(gè)不同的區(qū)域。一般情況下將堆區(qū)劃分為老年代和新生代悉尾,在堆區(qū)之外還有一個(gè)永久代突那。老年代的特點(diǎn)就是每次垃圾回收時(shí)只有少量的對(duì)象需要被回收,而新生代每次回收時(shí)都有大量的對(duì)象需要被回收构眯,于是該算法就是根據(jù)這些代的特點(diǎn)采取合適的收集算法
接下來(lái)就逐一介紹下這些代的區(qū)別和對(duì)應(yīng)的回收算法:
1.年輕代
回收算法以Copying為主,新創(chuàng)建的對(duì)象都存放在這里愕难。因?yàn)榇蠖鄶?shù)對(duì)象很快變得不可達(dá),所以大多數(shù)對(duì)象在年輕代中創(chuàng)建惫霸,然后消失猫缭。當(dāng)對(duì)象從這塊內(nèi)存區(qū)域消失時(shí),我們說(shuō)發(fā)生了一次“minor GC”(次要回收)
所有新生成的對(duì)象首先都是放在年輕代的壹店。年輕代的目標(biāo)就是盡可能快速的收集掉那些生命周期短的對(duì)象猜丹。
新生代內(nèi)存按照8:1:1的比例分為一個(gè)eden(伊甸)區(qū)和兩個(gè)survivor(幸存)(survivor0->surviverFrom,survivor1->survivoerTo)區(qū)。一個(gè)Eden區(qū)茫打,兩個(gè) Survivor區(qū)(一般而言)居触。大部分對(duì)象在Eden區(qū)中生成±铣啵回收時(shí)先將eden區(qū)存活對(duì)象復(fù)制到一個(gè)survivor0區(qū),然后清空eden區(qū)制市,當(dāng)這個(gè)survivor0區(qū)也存放滿了時(shí)抬旺,則將eden區(qū)和survivor0區(qū)存活對(duì)象復(fù)制到另一個(gè)survivor1區(qū),然后清空eden和這個(gè)survivor0區(qū)祥楣,此時(shí)survivor0區(qū)是空的开财,然后將survivor0區(qū)和survivor1區(qū)交換汉柒,即保持survivor1區(qū)為空, 如此往復(fù)责鳍。
當(dāng)survivor1區(qū)不足以存放 eden和survivor0的存活對(duì)象時(shí)碾褂,就將存活對(duì)象直接存放到老年代。若是老年代也滿了就會(huì)觸發(fā)一次Full GC(Major GC)历葛,也就是新生代正塌、老年代都進(jìn)行回收。
新生代發(fā)生的GC叫做Minor GC恤溶,MinorGC發(fā)生頻率比較高(不一定等Eden區(qū)滿了才觸發(fā))乓诽。
2.老年代
回收算法主要以標(biāo)記-整理算法Mark-Compact為主,沒(méi)有變得不可達(dá),存活下來(lái)的年輕代對(duì)象被復(fù)制到這里咒程。這塊內(nèi)存區(qū)域一般大于年輕代鸠天。因?yàn)樗蟮囊?guī)模,GC發(fā)生的次數(shù)比在年輕代的少帐姻。對(duì)象從老年代消失時(shí)稠集,我們說(shuō)“major GC”(或“full GC”)發(fā)生了
在年輕代中經(jīng)歷了N次垃圾回收后仍然存活的對(duì)象剥纷,就會(huì)被放到年老代中扛伍。因此刺洒,可以認(rèn)為年老代中存放的都是一些生命周期較長(zhǎng)的對(duì)象。
內(nèi)存比新生代也大很多(大概比例是1:2)鼎文,當(dāng)老年代內(nèi)存滿時(shí)觸發(fā)Major GC即Full GC因俐,F(xiàn)ull GC發(fā)生頻率比較低抹剩,老年代對(duì)象存活時(shí)間比較長(zhǎng),存活率標(biāo)記高胡嘿。
3.永久代
用于存放靜態(tài)文件钳踊,如Java類(lèi)、方法等缴罗。持久代對(duì)垃圾回收沒(méi)有顯著影響,但是有些應(yīng)用可能動(dòng)態(tài)生成或者調(diào)用一些class兵钮,例如Hibernate 等矢空,在這種時(shí)候需要設(shè)置一個(gè)比較大的永久代空間來(lái)存放這些運(yùn)行過(guò)程中新增的類(lèi)禀横。
??注意:這塊內(nèi)存區(qū)域絕對(duì)不是永久的存放從老年代存活下來(lái)的對(duì)象的!!!在這塊內(nèi)存中有可能發(fā)生垃圾回收。發(fā)生在這里垃圾回收也被稱(chēng)為major GC
G1
G1(Garbage-First)回收器是在JDK1.7中正式使用的全新垃圾回收器酿箭,G1擁有獨(dú)特的垃圾回收策略缭嫡,從分代上看抬闷,G1依然屬于分代垃圾回收器,它會(huì)區(qū)分年代和老年代评架,依然有eden和survivor區(qū)纵诞,但從堆的結(jié)構(gòu)上看培遵,它并不要求整個(gè)eden區(qū)、年清代或者老年代都連續(xù)嗡呼。它使用了全新的分區(qū)算法晤锥。其特點(diǎn)如下:
并行性:G1在回收期間廊宪,可以由多個(gè)GC線程同時(shí)工作,有效利用多核計(jì)算能力壕翩。
并發(fā)性:G1擁有與應(yīng)用程序交替執(zhí)行的能力放妈,因此一般來(lái)說(shuō)荐操,不會(huì)在整個(gè)回收期間完全阻塞應(yīng)用程序。
分代GC:與之前回收器不同宅倒,其他回收器拐迁,它們要么工作在年輕代要么工作在老年代疗绣。G1可以同時(shí)兼顧年輕代與老年代。
空間整理:G1在回收過(guò)程中缓淹,會(huì)進(jìn)行適當(dāng)?shù)膶?duì)象移動(dòng)讯壶,不像CMS患雏,只是簡(jiǎn)單的標(biāo)記清除,在若干次GC后CMS必須進(jìn)行一次碎片整理丙挽,G1在每次回收時(shí)都會(huì)有效的復(fù)制對(duì)象颜阐,減少空間碎片吓肋。
可預(yù)見(jiàn)性:由于分區(qū)的原因,G1可以只選取部分區(qū)域進(jìn)行內(nèi)存回收肤舞,這樣縮小了回收范圍李剖,因此對(duì)于全局停頓也能得到更好的控制。