初步學習JVM底層原理(二)

Java之JVM垃圾回收 內(nèi)存結(jié)構(gòu)以及垃圾回收算法

作為Java語言的核心之一向拆,JVM垃圾回收幫我們解決了讓我們很頭疼的垃圾回收問題萌朱。我們不需要像VC++一樣,作為內(nèi)存管理的統(tǒng)治者需要我們對我們分配的每一塊內(nèi)存進行回收,否則就會造成內(nèi)存泄露問題于置。

是不是只要有JVM存在我們就不會出現(xiàn)內(nèi)存泄露問題,出現(xiàn)內(nèi)存泄露問題我們又該怎么辦贞岭,如果我們想提高我們程序的穩(wěn)定性和其他性能我們能從什么地方下手0颂骸!瞄桨!相信這些問題是我們程序過程中不可逾越的话速。了解JVM的內(nèi)存分配及其相應(yīng)的垃圾回收機制,不僅僅是可以了解底層的JVM運行機制芯侥,而且對于程序性能的優(yōu)化和提升還是很有必要的泊交。

一.JVM堆內(nèi)存介紹

工欲善其事,必先利其器柱查。所以了解堆內(nèi)存的內(nèi)部結(jié)構(gòu)是很必要的廓俭。
在JVM中堆空間劃分為三個代:年輕代(Young Generation)、年老代(Old Generation)和永久代(Permanent Generation)物赶。年輕帶主要是動態(tài)的存儲白指,年輕帶主要儲存新產(chǎn)生的對象,年老代儲存年齡大些的對象酵紫,永久帶主要是存儲的是java的類信息告嘲,包括解析得到的方法错维、屬性、字段等橄唬。永久帶基本不參與垃圾回收赋焕。所以說我們說的垃圾回收主要是針對年輕代和年老代。
年輕代又分成3個部分仰楚,一個eden區(qū)和兩個相同的survior區(qū)隆判。剛開始創(chuàng)建的對象都是放置在eden區(qū)的。分成這樣3個部分僧界,主要是為了生命周期短的對象盡量留在年輕帶侨嘀。當eden區(qū)申請不到空間的時候,進行minorGC捂襟,把存活的對象拷貝到survior咬腕。年老代主要存放生命周期比較長的對象,比如緩存對象葬荷。(經(jīng)過IBM的一個研究機構(gòu)研究數(shù)據(jù)表明涨共,基本上80%-98%的對象都會在年輕代的Eden區(qū)死掉從而本回收掉,所以說真正進入到老年代的對象很少宠漩,這也是為什么MinorGC比MajorGC更加頻繁的原因)

具體JVM內(nèi)存垃圾回收過程描述如下 :
1举反、對象在Eden區(qū)完成內(nèi)存分配
2、當Eden區(qū)滿了扒吁,再創(chuàng)建對象火鼻,會因為申請不到空間,觸發(fā)minorGC瘦陈,進行young(eden+1survivor)區(qū)的垃圾回收
3凝危、minorGC時,Eden不能被回收的對象被放入到空的survivor(Eden肯定會被清空)晨逝,另一個survivor里不能被GC回收的對象也會被放入這個survivor,始終保證一個survivor是空的
4懦铺、當做第3步的時候捉貌,如果發(fā)現(xiàn)survivor滿了,則這些對象被copy到old區(qū)冬念,或者survivor并沒有滿趁窃,但是有些對象已經(jīng)足夠Old,也被放入Old區(qū) XX:MaxTenuringThreshold
5急前、當Old區(qū)被放滿的之后醒陆,進行fullGC
補充:
MinorGC:年輕代所進行的垃圾回收,非常頻繁裆针,一般回收速度也比較快刨摩。
MajorGC:老年代進行的垃圾回收寺晌,發(fā)生一次MajorGC至少伴隨一次MinorGC,一般比MinorGC速度慢十倍以上澡刹。
FullGC:整個堆內(nèi)存進行的垃圾回收呻征,很多時候是MajorGC
以后就是堆內(nèi)存結(jié)構(gòu)已經(jīng)大致的垃圾回收過程。

二罢浇、對象分配原則

1.對象優(yōu)先分配在Eden區(qū)陆赋,如果Eden區(qū)沒有足夠的空間時,虛擬機執(zhí)行一次Minor GC嚷闭。

2.大對象直接進入老年代(大對象是指需要大量連續(xù)內(nèi)存空間的對象)攒岛。這樣做的目的是避免在Eden區(qū)和兩個Survivor區(qū)之間發(fā)生大量的內(nèi)存拷貝(新生代采用復(fù)制算法收集內(nèi)存)。

3.長期存活的對象進入老年代胞锰。虛擬機為每個對象定義了一個年齡計數(shù)器灾锯,如果對象經(jīng)過了1次Minor GC那么對象會進入Survivor區(qū),之后每經(jīng)過一次Minor GC那么對象的年齡加1胜蛉,知道達到閥值對象進入老年區(qū)挠进。

4.動態(tài)判斷對象的年齡。如果Survivor區(qū)中相同年齡的所有對象大小的總和大于Survivor空間的一半誊册,年齡大于或等于該年齡的對象可以直接進入老年代领突。

5.空間分配擔保。每次進行Minor GC時案怯,JVM會計算Survivor區(qū)移至老年區(qū)的對象的平均大小君旦,如果這個值大于老年區(qū)的剩余值大小則進行一次Full GC,如果小于檢查HandlePromotionFailure設(shè)置嘲碱,如果true則只進行Monitor GC,如果false則進行Full GC金砍。

三、垃圾收集器

作為JVM中的核心之一垃圾收集器麦锯,主要完成的功能包括:(1)發(fā)現(xiàn)無用信息對象恕稠;(2)回收被無用對象占用的內(nèi)存空間,使該空間可被程序再次使用扶欣。所以說我們在實現(xiàn)垃圾收集器的同時就要實現(xiàn)兩個算法一個是發(fā)現(xiàn)無用的對象第二就是回收該對象的內(nèi)存鹅巍。

收集器主要分為引用計數(shù)器和跟蹤收集器兩種,Sun JDK中采用跟蹤收集器作為GC實現(xiàn)策略料祠。發(fā)現(xiàn)無用對象只要的實現(xiàn)算法包括引用計數(shù)法和根搜索算法骆捧,引用計數(shù)法主要是JVM的早期實現(xiàn)方法,因為引用計數(shù)無法解決循環(huán)引用的問題髓绽,所以現(xiàn)在JVM實現(xiàn)的主要是根搜索算法敛苇,

引用計數(shù)法:堆中的每個對象對應(yīng)一個引用計數(shù)器。當每一次創(chuàng)建一個對象并賦給一個變量時顺呕,引用計數(shù)器置為1枫攀。當對象被賦給任意變量時括饶,引用計數(shù)器每次加1當對象出了作用域后(該對象丟棄不再使用),引用計數(shù)器減1脓豪,一旦引用計數(shù)器為0巷帝,對象就不可用從而可以被回收。 根搜索算法:通過一系列的名為“GC Roots”的對象作為起始點扫夜,從這些節(jié)點開始向下搜索楞泼,搜索所走過的路徑稱為引用鏈(Reference Chain),當一個對象到GC Roots沒有任何引用鏈相連(用圖論的話來說就是從GC Roots到這個對象不可達)時笤闯,則證明此對象是不可用的堕阔。

目前的收集器主要有三種

串行收集器:使用單線程處理所有垃圾回收工作,因為無需多線程交互颗味,所以效率比較高

并行收集器:對年輕代進行并行垃圾回收超陆,因此可以減少垃圾回收時間。一般在多線程多處理器機器上使用

并發(fā)收集器:可以保證大部分工作都并發(fā)進行(應(yīng)用不停止)浦马,垃圾回收只暫停很少的時間时呀,此收集器適合對響應(yīng)時間要求比較高的中、大規(guī)模應(yīng)用

四晶默、垃圾收集器的回收算法

Copying算法:

算法:復(fù)制采用的方式為從根集合掃描出存活的對象谨娜,并將找到的存活對象復(fù)制到一塊新的完全未使用的空間中。

過程: 此算法把內(nèi)存空間劃為兩個相等的區(qū)域磺陡,每次只使用其中一個區(qū)域趴梢。垃圾回收時,遍歷當前使用區(qū)域币他,把正在使用中的對象復(fù)制到另外一個區(qū)域中坞靶。次算法每次只處理正在使用中的對象,因此復(fù)制成本比較小蝴悉,同時復(fù)制過去以后還能進行相應(yīng)的內(nèi)存整理彰阴,不過出現(xiàn)“碎片”問題。當然拍冠,此算法的缺點也是很明顯的硝枉,就是需要兩倍內(nèi)存空間。

image

Mark-Sweep算法:

算法:標記-清除采用的方式為從根集合開始掃描倦微,對存活的對象進行標記,標記完畢后正压,再掃描整個空間中未標記的對象欣福,并進行回收。

過程: 第一階段從引用根節(jié)點開始標記所有被引用的對象焦履,第二階段遍歷整個堆拓劝,把未標記的對象清除雏逾。它停止所有工作,收集器從根開始訪問每一個活躍的節(jié)點郑临,標記它所訪問的每一個節(jié)點栖博。走過所有引用后,收集就完成了厢洞,然后就對堆進行清除(即對堆中的每一個對象進行檢查)仇让,所有沒有標記的對象都作為垃圾回收并返回空閑列表。

image

Mark-Compact算法:

算法:標記階段與“Mark-Sweep”算法相同躺翻,但在清除階段有所不同丧叽。在回收不存活對象所占用的內(nèi)存空間后,會將其他所有存活對象都往左端空閑的空間進行移動公你,并更新引用其對象指針踊淳。

過程:此算法結(jié)合了“標記-清除”和“復(fù)制”兩個算法的優(yōu)點。也是分兩階段陕靠,第一階段從根節(jié)點開始標記所有被引用對象迂尝,第二階段遍歷整個堆,把清除未標記對象并且把存活對象“壓縮”到堆的其中一塊剪芥,按順序排放垄开。此算法避免了“標記-清除”的碎片問題,同時也避免了“復(fù)制”算法的空間問題粗俱。

image

Sun JDK GC策略:

image

新生代算法實現(xiàn):Copying,Copying,Copying

舊生代算發(fā)實現(xiàn):Mark-Sweep-Compact说榆,Mark –Compact,Mark –Sweep4缛稀签财!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市偏塞,隨后出現(xiàn)的幾起案子唱蒸,更是在濱河造成了極大的恐慌,老刑警劉巖灸叼,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件神汹,死亡現(xiàn)場離奇詭異,居然都是意外死亡古今,警方通過查閱死者的電腦和手機屁魏,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來捉腥,“玉大人氓拼,你說我怎么就攤上這事。” “怎么了桃漾?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵坏匪,是天一觀的道長。 經(jīng)常有香客問我撬统,道長适滓,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任恋追,我火速辦了婚禮凭迹,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘几于。我一直安慰自己蕊苗,他們只是感情好,可當我...
    茶點故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布沿彭。 她就那樣靜靜地躺著朽砰,像睡著了一般。 火紅的嫁衣襯著肌膚如雪喉刘。 梳的紋絲不亂的頭發(fā)上瞧柔,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天,我揣著相機與錄音睦裳,去河邊找鬼造锅。 笑死,一個胖子當著我的面吹牛廉邑,可吹牛的內(nèi)容都是我干的哥蔚。 我是一名探鬼主播,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼蛛蒙,長吁一口氣:“原來是場噩夢啊……” “哼糙箍!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起牵祟,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤深夯,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后诺苹,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體咕晋,經(jīng)...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年收奔,在試婚紗的時候發(fā)現(xiàn)自己被綠了掌呜。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,779評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡坪哄,死狀恐怖站辉,靈堂內(nèi)的尸體忽然破棺而出呢撞,到底是詐尸還是另有隱情,我是刑警寧澤饰剥,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站摧阅,受9級特大地震影響汰蓉,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜棒卷,卻給世界環(huán)境...
    茶點故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一顾孽、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧比规,春花似錦若厚、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至灾常,卻和暖如春霎冯,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背钞瀑。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工沈撞, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人雕什。 一個月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓缠俺,卻偏偏與公主長得像,于是被迫代替她去往敵國和親贷岸。 傳聞我的和親對象是個殘疾皇子壹士,可洞房花燭夜當晚...
    茶點故事閱讀 44,700評論 2 354

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

  • jvm原理 Java虛擬機是整個java平臺的基石墓卦,是java技術(shù)實現(xiàn)硬件無關(guān)和操作系統(tǒng)無關(guān)的關(guān)鍵環(huán)節(jié),是java...
    AI喬治閱讀 17,242評論 21 486
  • 轉(zhuǎn)載blog.csdn.net/ning109314/article/details/10411495/ JVM工...
    forever_smile閱讀 5,366評論 1 56
  • JVM架構(gòu) 當一個程序啟動之前户敬,它的class會被類裝載器裝入方法區(qū)(Permanent區(qū))落剪,執(zhí)行引擎讀取方法區(qū)的...
    cocohaifang閱讀 1,664評論 0 7
  • 1.一些概念 1.1.數(shù)據(jù)類型 Java虛擬機中,數(shù)據(jù)類型可以分為兩類:基本類型和引用類型尿庐≈也溃基本類型的變量保存原始...
    落落落落大大方方閱讀 4,540評論 4 86
  • 原文閱讀 前言 這段時間懈怠了,罪過抄瑟! 最近看到有同事也開始用上了微信公眾號寫博客了凡泣,挺好的~給他們點贊,這博客我...
    碼農(nóng)戲碼閱讀 5,962評論 2 31