JVM內(nèi)存模型和GC的解析

jvm內(nèi)存模型
  • JVM調(diào)優(yōu)是調(diào)整:方法區(qū)和堆(主要是堆)
  • 棧管運行陌宿,堆管存儲
  • 堆和方法區(qū)是所有線程共享的內(nèi)存區(qū)域咆疗;棧和程序計數(shù)器是每個線程私有的內(nèi)存區(qū)域涧黄。
    注:由于棧是每個線程私有的篮昧,棧空間是每個線程的運行內(nèi)存
  • 運行時數(shù)據(jù)區(qū)也就是我們的JVM內(nèi)存模型區(qū)域笋妥。JVM在運行程序時會將他擁有的內(nèi)存 邏輯性的劃分懊昨,讓每部分內(nèi)存做它該做的事情。

類加載器(class loader):

加載 .class文件春宣,生成類模板酵颁。(只負責(zé)類的加載,能不能運行要看Execution Engine執(zhí)行引擎)

  • 類加載器分為:
    • 啟動類加載器
    • 擴展類加載器
    • 應(yīng)用類加載器

雙親委派機制:往上拋月帝,上面的如果可以加載躏惋,就用上面的

本地方法接口(Native Interface):調(diào)用C/C++的本地庫
本地方法棧(Native Method Stack):讓執(zhí)行引擎加載本地方法
程序計數(shù)器:用來存儲指向下一條指令的地址,也即將要執(zhí)行的指令代碼
執(zhí)行引擎(Execution Engine):負責(zé)解釋命令,提交操作系統(tǒng)執(zhí)行


棧(stack):

  • 每個線程都有一個私有的棧嚷辅,隨著線程的創(chuàng)建而創(chuàng)建
  • 棧存儲8種基本數(shù)據(jù)類型 + 引用變量(存儲堆中地址)+ 實例方法
  • 壓棧簿姨,先進后出
  • java.lang.StackOverFlowError 棧溢出異常(創(chuàng)建的引用太多,或死循環(huán))

方法區(qū)(Method Area):

存儲 靜態(tài)變量簸搞,常量扁位,類模板(構(gòu)造方法/接口定義)

堆(heap)

分為三個區(qū)域

  • 新生代
    • 伊甸園區(qū)
    • 幸存0區(qū)
    • 幸存1區(qū)
  • 老年代
  • 永久代
  1. 新生代 + 老年代 = 實際堆內(nèi)存
  2. java1.7永久代 = 方法區(qū)(存放靜態(tài)變量,常量趁俊,類模板)域仇;
    java1.8永久代 = 方法區(qū)(存放靜態(tài)變量,常量)+本地內(nèi)存-元空間(存放類模板), 改善了之前依賴的jar包太多寺擂,加載的類模板太多暇务,啟動項目時會出現(xiàn)永久區(qū)OOM:PermGen space的情況
  3. 空間占用
    · 新生代占堆空間的1/3泼掠,其中伊甸園區(qū):From區(qū):To區(qū) = 8:1:1
    · 老年代占堆空間的2/3




GC(Garbage Collection)

分代垃圾收集算法:新生代和老年代的收集算法不同

  • 頻繁收集新生代:minorGC 輕量級GC—使用復(fù)制算法
  • 較少收集老年代:majorGC,也叫fullGC:使用標(biāo)記清除算法般卑,標(biāo)記清除壓縮算法
  • 基本不動永久代

majorGC速度比minorGC慢10倍以上

GC的四種回收算法:

  1. 引用計數(shù)法(native源碼中有武鲁,但不使用):維護一個kv結(jié)構(gòu)爽雄,key為變量蝠检,v為引用次數(shù),每次清理v=0的變量挚瘟;
    · 缺點:變量互相引用后叹谁,如果將變量賦值為null,此時對象會沒有引用乘盖,但對象的v>0焰檩,不會被清除


    下列算法使用 可達性分析算法 判斷對象是否被引用:被棧、方法區(qū)正在引用著的對象订框,是可達對象析苫;清理沒有引用的對象(清理不可達對象)。

  2. 復(fù)制算法:只復(fù)制可達的對象到to區(qū)(幸存0/1區(qū))穿扳,其余對象全部清除衩侥;
    優(yōu)點:沒有內(nèi)存碎片
    缺點:因為只復(fù)制存活的對象,所以復(fù)制算法適用于存活率較低的場景(新生代)矛物;如果因為代碼問題導(dǎo)致存活率較高時茫死,復(fù)制的時間會越來越長。且復(fù)制算法的內(nèi)存占用大

  3. 標(biāo)記清除算法(Mark-Sweep):顧名思義履羞,將可達對象標(biāo)記后峦萎,清除不可達對象
    優(yōu)點:內(nèi)存占用較小
    缺點:清除后內(nèi)存空間不連續(xù)會生成內(nèi)存碎片

4、標(biāo)記清除壓縮算法(Mark-Sweep-Compact):多次標(biāo)記清除后忆首,才觸發(fā)壓縮操作爱榔。有效減少壓縮的執(zhí)行時間(GMS老年代實際使用的算法


擴展:標(biāo)記清除其實是三次標(biāo)記,一次清除糙及,第1详幽、3次標(biāo)記時會stop the world

標(biāo)記清除的步驟

所以如果remark標(biāo)記階段把A對象標(biāo)記為1,而程序運行時又將A變?yōu)榭蛇_對象丁鹉,但A仍然會被清除


?????? new對象的時候妒潭,對象會出生在伊甸園區(qū),當(dāng)伊甸園區(qū)滿了揣钦,會執(zhí)行minorGC(輕量級GC)雳灾,伊甸園區(qū)沒有引用的對象和幸存0區(qū)(from區(qū))沒有引用的對象,大約98%的對象會被minorGC回收冯凹,存活的對象copy(復(fù)制算法)到幸存1區(qū)(to區(qū))谎亩,然后將存儲對象的to區(qū)變成from區(qū)炒嘲,將空的from區(qū)變成to區(qū),幸存對象的年齡會加1匈庭;
?????? 當(dāng)伊甸園區(qū)又滿了之后夫凸,新的from區(qū)(里面是上次minorGC后幸存的對象)中沒有引用的對象和伊甸園區(qū)沒有引用的對象,會被minorGC回收阱持,當(dāng)幸存對象的年齡達到15夭拌,這個對象將會存儲到老年代。
?????? 當(dāng)老年代滿了之后會執(zhí)行majorGC(重量級GC)使用標(biāo)記清除壓縮算法衷咽,先標(biāo)記幸存對象鸽扁,清除被未標(biāo)記的對象;多次清理后镶骗,整理成內(nèi)存連續(xù)的空間
注:當(dāng)minorGC執(zhí)行后桶现,將存活的對象copy到To區(qū)時,如果To區(qū)內(nèi)存不夠鼎姊,會直接將剩下的對象放入老年代骡和,所以某些特定場景下可以增大幸存0/1區(qū)的內(nèi)存,減少對象進入老年代的數(shù)量相寇,從而減少fullGC


堆內(nèi)存溢出問題的原因和解決辦法:
1慰于、JVM堆內(nèi)存設(shè)置不夠
2、老年代滿了(存在大量對象裆赵,不能被GC清理东囚,對象有引用)
上述問題會引起java.lang.OutOfMemoryError:java heap space 堆內(nèi)存溢出異常。

解決辦法
可以分析MAT(Eclipse Memory Analyzer 內(nèi)存分析器)
· 分析dump快照文件战授,快速定位內(nèi)存泄漏
· 獲取堆中對象的數(shù)據(jù)
· 獲取對象相互引用的關(guān)系
具體步驟參照另一篇文章:一次線上JVM內(nèi)存泄漏的分析和解決


JVM的基礎(chǔ)調(diào)優(yōu)策略

堆內(nèi)存分配示意圖

堆內(nèi)存調(diào)優(yōu)常用參數(shù)解析:
-Xms :分配初始內(nèi)存页藻,默認物理內(nèi)存的1/64
-Xmx:分配最大內(nèi)存,默認為物理內(nèi)存的1/4
-XX:MaxTenuringThreshold:對象進入老年區(qū)要經(jīng)過minorGC的次數(shù)閾值植兰,默認15份帐,經(jīng)驗值31

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市楣导,隨后出現(xiàn)的幾起案子废境,更是在濱河造成了極大的恐慌,老刑警劉巖筒繁,帶你破解...
    沈念sama閱讀 206,482評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件噩凹,死亡現(xiàn)場離奇詭異,居然都是意外死亡毡咏,警方通過查閱死者的電腦和手機驮宴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來呕缭,“玉大人堵泽,你說我怎么就攤上這事修己。” “怎么了迎罗?”我有些...
    開封第一講書人閱讀 152,762評論 0 342
  • 文/不壞的土叔 我叫張陵睬愤,是天一觀的道長。 經(jīng)常有香客問我纹安,道長尤辱,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,273評論 1 279
  • 正文 為了忘掉前任钻蔑,我火速辦了婚禮啥刻,結(jié)果婚禮上奸鸯,老公的妹妹穿的比我還像新娘咪笑。我一直安慰自己,他們只是感情好娄涩,可當(dāng)我...
    茶點故事閱讀 64,289評論 5 373
  • 文/花漫 我一把揭開白布窗怒。 她就那樣靜靜地躺著,像睡著了一般蓄拣。 火紅的嫁衣襯著肌膚如雪扬虚。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,046評論 1 285
  • 那天球恤,我揣著相機與錄音辜昵,去河邊找鬼。 笑死咽斧,一個胖子當(dāng)著我的面吹牛堪置,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播张惹,決...
    沈念sama閱讀 38,351評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼舀锨,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了宛逗?” 一聲冷哼從身側(cè)響起坎匿,我...
    開封第一講書人閱讀 36,988評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎雷激,沒想到半個月后替蔬,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,476評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡屎暇,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,948評論 2 324
  • 正文 我和宋清朗相戀三年承桥,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片恭垦。...
    茶點故事閱讀 38,064評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡快毛,死狀恐怖格嗅,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情唠帝,我是刑警寧澤屯掖,帶...
    沈念sama閱讀 33,712評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站襟衰,受9級特大地震影響贴铜,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜瀑晒,卻給世界環(huán)境...
    茶點故事閱讀 39,261評論 3 307
  • 文/蒙蒙 一绍坝、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧苔悦,春花似錦轩褐、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至蟋座,卻和暖如春拗踢,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背向臀。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評論 1 262
  • 我被黑心中介騙來泰國打工巢墅, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人券膀。 一個月前我還...
    沈念sama閱讀 45,511評論 2 354
  • 正文 我出身青樓君纫,卻偏偏與公主長得像,于是被迫代替她去往敵國和親三娩。 傳聞我的和親對象是個殘疾皇子庵芭,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,802評論 2 345

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