java gc

參考
新生代老生代
垃圾回收算法參考
優(yōu)化參考
面向GC編程
Java 堆內(nèi)存
面試GC問答

一、算法
  • 引用計數(shù)法:一個對象被引用計數(shù)器加一,取消引用計數(shù)器減一友驮,引用計數(shù)器為0才能被回收疼鸟。優(yōu)點:簡單殴蓬。缺點:不能解決循環(huán)引用的問題立润,比如A引用B狂窑,B引用A,但是這兩個對象沒有被其他任何對象引用桑腮,屬于垃圾對象泉哈,卻不能回收;每次引用都會附件一個加減法破讨,影響性能丛晦。
    引用計數(shù)的方法由于存在顯著的缺點,實際上并未被JVM所使用提陶。

  • 標(biāo)記清除法:分為兩個階段:標(biāo)記階段和清除階段烫沙。標(biāo)記階段通過根節(jié)點標(biāo)記所有可達(dá)對象,清除階段清除所有不可達(dá)對象隙笆。缺點:因為清除不可達(dá)對象之后剩余的內(nèi)存不連續(xù)斧吐,會產(chǎn)生大量內(nèi)存碎片,不利于大對象的分配仲器。由于無法找到足夠的連續(xù)內(nèi)存煤率,不得不觸發(fā)另一次GC。
    可以做根節(jié)點的對象:

  • 虛擬機(jī)棧(棧幀中的本地變量表)中的引用的對象

  • 方法區(qū)中的類靜態(tài)屬性引用的對象

  • 方法區(qū)中的常量引用的對象

  • 本地方法棧中JNI(Native方法)的引用對象

  • 復(fù)制算法:將內(nèi)存空間分成相同的兩塊乏冀,每次只是用其中的一塊蝶糯,垃圾回收時,將正在使用的內(nèi)存中的存活對象復(fù)制到另外一塊空間辆沦,然后清除正在使用的內(nèi)存空間中的所有對象昼捍,這種回收算法適用于新生代垃圾回收。優(yōu)點:垃圾回收對象比較多時需要復(fù)制的對象很少肢扯,性能較好妒茬;不會存在內(nèi)存碎片。缺點:將系統(tǒng)內(nèi)存折半蔚晨。

  • 標(biāo)記壓縮算法:是一種老年代回收算法乍钻,在標(biāo)記清除的基礎(chǔ)上做了一些優(yōu)化,首先從根節(jié)點開始標(biāo)記所有不可達(dá)的對象铭腕,然后將所有可達(dá)的對象移動到內(nèi)存的一端银择,最后清除所有不可達(dá)的對象。優(yōu)點:不用將內(nèi)存分為兩塊累舷;不會產(chǎn)生內(nèi)存碎片浩考。

  • 分代算法:新生代使用復(fù)制算法,老生代使用標(biāo)記清除算法或者標(biāo)記壓縮算法被盈。幾乎所有的垃圾回收期都區(qū)分新生代和老生帶析孽。

  • 分區(qū)算法:將整個堆空間分成很多個連續(xù)的不同的小空間搭伤,每個小空間獨立使用,獨立回收袜瞬。為了更好的控制gc停頓時間怜俐,可以根據(jù)目標(biāo)停頓時間合理地回收若干個小區(qū)間,而不是整個堆空間吞滞,從而減少gc停頓時間佑菩。

二盾沫、新生代young generation(執(zhí)行minor gc 復(fù)制算法)和老年代old generation(執(zhí)行major gc或叫full gc標(biāo)記清除算法)
  • 為什么要分代裁赠?
    總有一些對象是長期使用的,如果每次GC都掃描他們赴精,然后發(fā)現(xiàn)無法回收佩捞,這樣效率就很差。所以就把對象增加了一個年齡屬性蕾哟,這樣如果每次GC都回收不掉他們一忱,他們的年齡就增加1,慢慢地就變成老年人了谭确。達(dá)到一定年齡后帘营,就要分區(qū)了。老年人會離開新生代區(qū)域逐哈,進(jìn)入老年代區(qū)域芬迄。這樣常規(guī)的GC只掃描新生代區(qū)域,處于老年代區(qū)域的對象就不會被頻繁地掃描了昂秃。
    80%的對象都是朝生夕死禀梳,對于負(fù)載不高的應(yīng)用,可能數(shù)月都不會發(fā)生FullGC肠骆。

  • 新生代再細(xì)分算途,有三個區(qū)域:Eden區(qū),即伊甸園區(qū)蚀腿。還有2個Survivor區(qū)嘴瓤,即幸存者區(qū),分別叫from和to莉钙。from和to這兩塊就是復(fù)制算法中提到的兩塊內(nèi)存纱注,它們互相復(fù)制來復(fù)制去,互相換著當(dāng)from和to.當(dāng)然其中有一個肯定是空的胆胰。當(dāng)eden滿時狞贱,minorgc開始,Eden區(qū)也會執(zhí)行復(fù)制算法蜀涨,把所有存活對象全部復(fù)制到to區(qū)域瞎嬉。from區(qū)域的對象會根據(jù)年齡決定去向蝎毡,達(dá)到要求的就去老年代,沒達(dá)到要求的也會進(jìn)入to區(qū)域氧枣。然后沐兵,Eden和from區(qū)都會被清空。當(dāng)to區(qū)域也被塞滿時便监,所有對象都會被復(fù)制到老年區(qū)扎谎。

  • 一個對象的一輩子:我是一個普通的Java對象,我出生在Eden區(qū)烧董,在Eden區(qū)我還看到和我長的很像的小兄弟毁靶,我們在Eden區(qū)中玩了挺長時間。有一天Eden區(qū)中的人實在是太多了逊移,我就被迫去了Survivor區(qū)的“From”區(qū)预吆,自從去了Survivor區(qū),我就開始漂了胳泉,有時候在Survivor的“From”區(qū)拐叉,有時候在Survivor的“To”區(qū),居無定所扇商。直到我18歲的時候凤瘦,爸爸說我成人了,該去社會上闖闖了案铺。于是我就去了年老代那邊蔬芥,年老代里义锥,人很多筋量,并且年齡都挺大的,我在這里也認(rèn)識了很多人镣衡。在年老代里暇番,我生活了20年(每次GC加一歲)嗤放,然后被回收。

  • 新生代98%的對象都是朝生夕死壁酬,虛擬機(jī)默認(rèn)eden和survivor大小比例是8次酌;1,也就是每次只有10%的內(nèi)存空間是作為to區(qū)域被浪費舆乔,而不是傳統(tǒng)復(fù)制算法中所說的浪費一半內(nèi)存岳服。

三、面向GC編程優(yōu)化
  • 減少創(chuàng)建對象的數(shù)量希俩,比如使用StringBuilder代替string
  • 老年代的GC很耗時吊宋,要減少進(jìn)入老年代的對象數(shù)量。比如對象池颜武,因為對象長期存活璃搜,會晉升到老年代拖吼,影響GC效率。另外對象池通常涉及并發(fā)訪問这吻,處理同步帶來的開銷也很大吊档。而重新創(chuàng)建一個對象的開銷,可能比這兩者都要小唾糯。
  • 在一個非常大的方法體內(nèi)怠硼,對于較大的對象,將其引用置為null移怯,某種程度可以幫助GC香璃。但大部分情況下這種行為意義不大。
  • 一些基于數(shù)組的數(shù)據(jù)結(jié)構(gòu)芋酌,例如StringBuilder增显、StringBuffer雁佳、ArrayList脐帝、HashMap等等,在擴(kuò)容的時候都需要做ArrayCopy糖权,對于不斷增長的結(jié)構(gòu)來說堵腹,經(jīng)過若干次擴(kuò)容,會存在大量無用的老數(shù)組星澳,而回收這些數(shù)組的壓力疚顷,全都會加在GC身上。這些容器的構(gòu)造函數(shù)中通常都有一個可以指定大小的參數(shù)禁偎,如果對于某些大小可以預(yù)估的容器腿堤,建議加上這個參數(shù)。
  • 盡可能縮小對象的作用域如暖,即生命周期笆檀。如果可以在方法內(nèi)聲明的局部變量,就不要聲明為實例變量盒至。除非你的對象是單例的或不變的酗洒,否則盡可能少地聲明static變量。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末枷遂,一起剝皮案震驚了整個濱河市樱衷,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌酒唉,老刑警劉巖矩桂,帶你破解...
    沈念sama閱讀 222,729評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異痪伦,居然都是意外死亡侄榴,警方通過查閱死者的電腦和手機(jī)阔籽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,226評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來牲蜀,“玉大人笆制,你說我怎么就攤上這事』链铮” “怎么了在辆?”我有些...
    開封第一講書人閱讀 169,461評論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長度苔。 經(jīng)常有香客問我匆篓,道長,這世上最難降的妖魔是什么寇窑? 我笑而不...
    開封第一講書人閱讀 60,135評論 1 300
  • 正文 為了忘掉前任鸦概,我火速辦了婚禮,結(jié)果婚禮上甩骏,老公的妹妹穿的比我還像新娘窗市。我一直安慰自己,他們只是感情好饮笛,可當(dāng)我...
    茶點故事閱讀 69,130評論 6 398
  • 文/花漫 我一把揭開白布咨察。 她就那樣靜靜地躺著,像睡著了一般福青。 火紅的嫁衣襯著肌膚如雪摄狱。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,736評論 1 312
  • 那天无午,我揣著相機(jī)與錄音媒役,去河邊找鬼。 笑死宪迟,一個胖子當(dāng)著我的面吹牛酣衷,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播踩验,決...
    沈念sama閱讀 41,179評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼鸥诽,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了箕憾?” 一聲冷哼從身側(cè)響起牡借,我...
    開封第一講書人閱讀 40,124評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎袭异,沒想到半個月后钠龙,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,657評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,723評論 3 342
  • 正文 我和宋清朗相戀三年碴里,在試婚紗的時候發(fā)現(xiàn)自己被綠了沈矿。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,872評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡咬腋,死狀恐怖羹膳,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情根竿,我是刑警寧澤陵像,帶...
    沈念sama閱讀 36,533評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站寇壳,受9級特大地震影響醒颖,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜壳炎,卻給世界環(huán)境...
    茶點故事閱讀 42,213評論 3 336
  • 文/蒙蒙 一泞歉、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧匿辩,春花似錦腰耙、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,700評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽涕滋。三九已至睬辐,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間宾肺,已是汗流浹背溯饵。 一陣腳步聲響...
    開封第一講書人閱讀 33,819評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留锨用,地道東北人丰刊。 一個月前我還...
    沈念sama閱讀 49,304評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像增拥,于是被迫代替她去往敵國和親啄巧。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,876評論 2 361

推薦閱讀更多精彩內(nèi)容