2018-09-13 JVM內(nèi)存管理+GC垃圾回收機(jī)制+JVM內(nèi)存調(diào)優(yōu)

主要題目出處:《近一個(gè)月的面試總結(jié)(java)》

一涮因、 JVM內(nèi)存管理機(jī)制(Java Virtual Machine)

JVM將內(nèi)存劃分為6個(gè)部分:

  1. PC寄存器(也叫程序計(jì)數(shù)器)記錄當(dāng)前線(xiàn)程運(yùn)行位置渴析,每個(gè)線(xiàn)程都有一個(gè)獨(dú)立的程序計(jì)數(shù)器铝噩,線(xiàn)程的阻塞免钻、回復(fù)绳慎、掛起等操作都需要程序計(jì)數(shù)器的參與甘萧,因此是線(xiàn)程私有的台夺。
  2. 虛擬機(jī)棧:創(chuàng)建線(xiàn)程時(shí)創(chuàng)建慨蛙,用來(lái)存儲(chǔ)棧幀辽聊,因此也是線(xiàn)程私有。java程序中的方法執(zhí)行時(shí)股淡,會(huì)創(chuàng)建一個(gè)棧幀身隐,用于存儲(chǔ)臨時(shí)數(shù)據(jù) 、中間結(jié)果唯灵、局部變量表贾铝、操作數(shù)棧、動(dòng)態(tài)鏈接、方法出口等信息垢揩。溢出會(huì)報(bào)StackOverflowError玖绿。
  3. :所有線(xiàn)程共享,用于存儲(chǔ)對(duì)象叁巨。堆空間不夠斑匪,同時(shí)無(wú)法申請(qǐng)足夠內(nèi)存時(shí),會(huì)報(bào)OutOfMemoryError锋勺。
  4. 方法區(qū):各個(gè)線(xiàn)程共享蚀瘸,存儲(chǔ)靜態(tài)變量、運(yùn)行時(shí)常量池等信息庶橱。
  5. 運(yùn)行時(shí)常量池:每個(gè)類(lèi)一個(gè)贮勃,從class常量池中遷移過(guò)來(lái),程序中使用的常量值苏章。
  6. 本地方法棧支持native方法寂嘉,如在java中調(diào)用C/C++。
    參考資料《面試總結(jié):java程序執(zhí)行過(guò)程 + JVM內(nèi)存管理 + GC垃圾回收機(jī)制》

二枫绅、 GC垃圾回收機(jī)制(Garbage Collection)

三個(gè)問(wèn)題:

  1. 哪些內(nèi)存需要回收泉孩?
線(xiàn)程私有 線(xiàn)程共享
程序計(jì)數(shù)器、虛擬機(jī)棧并淋、本地方法棧 java堆寓搬,方法區(qū)
線(xiàn)程銷(xiāo)毀,內(nèi)存自動(dòng)釋放预伺,總大小已定 內(nèi)存空間動(dòng)態(tài)分配订咸,所以需要?jiǎng)討B(tài)回收
  1. 何時(shí)回收?
  • 引用計(jì)數(shù)法:對(duì)某個(gè)對(duì)象a酬诀,若給a賦有效值脏嚷,則a的引用計(jì)數(shù)增加1,否則減少1瞒御,當(dāng)引用次數(shù)為0時(shí)父叙,即可回收。
    該方法存在問(wèn)題:a=1;a=2;a=null;時(shí)肴裙,雖然顯式清空趾唱,但是引用計(jì)數(shù)仍為1,GC不回收蜻懦。
  • 可達(dá)性分析:設(shè)立若干根對(duì)象甜癞,每個(gè)對(duì)象都是一個(gè)子節(jié)點(diǎn),當(dāng)一個(gè)對(duì)象找不到根的時(shí)候宛乃,認(rèn)為其不可達(dá)悠咱。
    根對(duì)象可以選擇:
    1蒸辆、java虛擬機(jī)棧中引用對(duì)象。
    2析既、方法區(qū)中靜態(tài)變量引用的對(duì)象躬贡。
    3、方法區(qū)中常量引用的對(duì)象眼坏。
    4拂玻、本地方法棧中引用的對(duì)象。
  1. 怎么回收宰译?
  • 標(biāo)記-清除算法:遍歷所有GC Root檐蚜。分別標(biāo)記所有可達(dá)與不可達(dá)對(duì)象,刪去其中不可達(dá)部分沿侈。
    優(yōu)點(diǎn):平庸而簡(jiǎn)便
    缺點(diǎn):效率低熬甚,回收空間不連續(xù)。
  • 復(fù)制算法:將內(nèi)存分為兩塊肋坚,每次只使用其中一塊,當(dāng)內(nèi)存滿(mǎn)了肃廓,就將仍存活對(duì)象復(fù)制到另一塊中智厌,并嚴(yán)格按照內(nèi)存地址排列,然后原先的那塊內(nèi)存統(tǒng)一回收盲赊。
    優(yōu)點(diǎn):能得到連續(xù)內(nèi)存空間
    缺點(diǎn):浪費(fèi)一半內(nèi)存
  • 分代算法:按照對(duì)象存活時(shí)間铣鹏,分成新生代、老年代哀蘑、永久代诚卸。
    新生代:蜉蝣于天地,朝生夕死绘迁,用復(fù)制算法批量刪合溺。
    老年代:有的人還活著,但是他已經(jīng)活的太久了缀台。所有同齡的都已逝去棠赛,所有新生的都尚未了解。沒(méi)有人記得他膛腐,他已經(jīng)在社會(huì)層面死亡了睛约。用標(biāo)記-清除算法抹去。
    永久代:不可以刪的如加載的class信息哲身,就不刪了留著吧辩涝。
    參考資料《面試總結(jié):java程序執(zhí)行過(guò)程 + JVM內(nèi)存管理 + GC垃圾回收機(jī)制》

三、 JVM內(nèi)存調(diào)優(yōu)

JVM內(nèi)存塊 = Permanent + Heap = (永久代) + (年輕代 + 年老代)
其中年輕代中存在一個(gè)Eden區(qū)勘天,以及兩個(gè)Survivor區(qū)怔揩。
大部分的對(duì)象都在Eden區(qū)生成捉邢,Eden滿(mǎn)了之后,仍存活的對(duì)象進(jìn)入Survivor區(qū)沧踏,兩個(gè)Survivor區(qū)執(zhí)行第二題中的復(fù)制算法歌逢。
經(jīng)過(guò)N(自定義)次Survivor滿(mǎn)引發(fā)的垃圾回收后,仍然存在的對(duì)象翘狱,可以進(jìn)入年老代秘案。
若年老代滿(mǎn)了,觸發(fā)一次Full GC潦匈,年輕代和年老代全部進(jìn)行清理阱高。如果仍然空間不夠,則報(bào)錯(cuò)茬缩。

內(nèi)存調(diào)優(yōu)
參數(shù)說(shuō)明

  • -client:設(shè)置JVM使用Client模式赤惊,啟動(dòng)快,但運(yùn)行時(shí)性能與內(nèi)存管理效率不高凰锡,用于客戶(hù)端程序或開(kāi)發(fā)調(diào)試未舟。32位環(huán)境直接運(yùn)行java程序默認(rèn)使用。

  • -server:設(shè)置JVM使用Server模式掂为,啟動(dòng)慢裕膀,但是性能和內(nèi)存管理效率高,適用于生產(chǎn)環(huán)境勇哗。64位JDK環(huán)境下默認(rèn)使用昼扛。

  • -Xmx3550m:設(shè)置JVM最大堆內(nèi)存為3550M

  • -Xms3550m:設(shè)置JVM初始堆內(nèi)存為3550M

  • -Xss128k:設(shè)置每個(gè)線(xiàn)程的棧大小

  • -Xmn2g:設(shè)置年輕代大小為2G,推薦采用整個(gè)堆大小的3/8

  • -XX:NewSize=1024m:設(shè)置年輕代初始值為1024M

  • -XX:MaxNewSize=1024m:設(shè)置年輕代最大值為1024M

  • -XX:PermSize=256m:設(shè)置持久代初始值為256M

  • -XX:NewRatio=4:設(shè)置年輕代(1+2)與年老代的比值

  • -XX:SurvivorRatio=4:設(shè)置年輕代中Eden區(qū)與Survivor區(qū)總大小的比值欲诺,此處表示Eden區(qū)占4/6,Survivor區(qū)每個(gè)子區(qū)占1/6

  • -XX:MaxTenuringThreshold=7:表示一個(gè)對(duì)象存活過(guò)幾次垃圾清理抄谐,就進(jìn)入年老區(qū)
    推薦使用Xmn,一次設(shè)定初始值和最大值扰法,且兩者相等蛹含。

三種垃圾回收器

  1. 串行收集器:適用于小數(shù)據(jù)量
  • -XX:+UseSerrialGC:設(shè)置串行收集器
  1. 并行收集器:吞吐量?jī)?yōu)先
  • -XX:+UseParallelGC:設(shè)置年輕代垃圾收集方式為并行收集
  • -XX:+UseParallelOldGC:設(shè)置年老代垃圾收集方式為并行收集
  • -XX:+ParallelGCThreads=20:設(shè)置并行收集器的線(xiàn)程數(shù),即同時(shí)有多少個(gè)線(xiàn)程一起進(jìn)行垃圾回收迹恐,一般與CPU數(shù)目相等挣惰。
  • -XX:+UseAdaptiveSizePolicy:并行處理器自動(dòng)調(diào)整年輕代Eden與Survivor區(qū)比例,以達(dá)到目標(biāo)系統(tǒng)規(guī)定指標(biāo)殴边。建議始終打開(kāi)憎茂。
  1. 并發(fā)收集器:響應(yīng)時(shí)間優(yōu)先
  • -XX:+UseConcMarkSweepGC:即CMS收集,設(shè)置年老代為并發(fā)收集
  • -XX:CMSFullGCsBeforeCompaction=0:并發(fā)收集器不自動(dòng)對(duì)內(nèi)存空間壓縮整理锤岸。一段時(shí)間后會(huì)產(chǎn)生內(nèi)存碎片竖幔,設(shè)置0次Full GC后,對(duì)內(nèi)存空間進(jìn)行整理是偷,即每次Full GC后拳氢,對(duì)內(nèi)存空間進(jìn)行整理募逞。

實(shí)際案例

  1. 大型網(wǎng)站服務(wù)器
    服務(wù)器配置:8 CPU, 8G MEM, JDK 1.6.X
    參數(shù)方案

-server(服務(wù)器端)
-Xmx3550m(JVM最大堆內(nèi)存3550M) -Xms3550m(JVM初始堆內(nèi)存3550M)
-Xmn1256m(年輕代大小1256M)
-Xss128k(線(xiàn)程棧大小128K)
-XX:SurvivorRatio=6(年輕代中Eden/Survivor大小=6:1)
-XX:MaxPermSize=256m(設(shè)置持久代最大值為256M)
-XX:ParallelGCThreads=8(并行收集器線(xiàn)程數(shù)為8)
-XX:MaxTenuringThreshold=0(N的初值為0)
-XX:+UseConcMarkSweepGC(設(shè)置年老代為并發(fā)收集)

調(diào)優(yōu)說(shuō)明

  • -Xms與-Xmx相同,避免重復(fù)申請(qǐng)內(nèi)存馋评。-Xmx約為系統(tǒng)內(nèi)存1/2放接,充分利用資源,同時(shí)確保安全的系統(tǒng)運(yùn)行空間留特。
  • -Xms大小纠脾,官方推薦為系統(tǒng)內(nèi)存3/8
  • 較小的線(xiàn)程棧,以支持更多線(xiàn)程蜕青。提升系統(tǒng)性能苟蹈。
  • Eden/Survivor大小,系統(tǒng)默認(rèn)是8右核,根據(jù)經(jīng)驗(yàn)設(shè)置6慧脱。
  • 并行收集器線(xiàn)程數(shù),一般等于CPU數(shù)
  • 設(shè)置垃圾最大年齡贺喝,年齡長(zhǎng)菱鸥,增加在年輕代回收概率。0表示直接進(jìn)入年老代躏鱼,適合年老代比較多的應(yīng)用采缚。
  • 并發(fā)的目的是減少應(yīng)用停止時(shí)間,適用于應(yīng)用中存在較多較長(zhǎng)生命周期的應(yīng)用挠他。
  1. 內(nèi)部集成服務(wù)器
    服務(wù)器配置:1 CPU, 4G MEM, JDK 1.6.X
    參數(shù)方案

-server
-XX:PermSize=196m -XX:MaxPermSize=196m
-Xmn320m -Xms768m -Xmx1024m

調(diào)優(yōu)說(shuō)明

  • 內(nèi)部集成服務(wù)器,可能需要加載大量java類(lèi)進(jìn)入內(nèi)存篡帕,因此持久代適當(dāng)開(kāi)大
  • 年輕代大小為整個(gè)堆3/8
  • 根據(jù)系統(tǒng)大小設(shè)置堆內(nèi)存大小即可

參考資料《JVM 內(nèi)存調(diào)優(yōu) 與 實(shí)際案例》

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末殖侵,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子镰烧,更是在濱河造成了極大的恐慌拢军,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,542評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件怔鳖,死亡現(xiàn)場(chǎng)離奇詭異茉唉,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)结执,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén)度陆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人献幔,你說(shuō)我怎么就攤上這事懂傀。” “怎么了蜡感?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,912評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵蹬蚁,是天一觀的道長(zhǎng)恃泪。 經(jīng)常有香客問(wèn)我,道長(zhǎng)犀斋,這世上最難降的妖魔是什么贝乎? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,449評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮叽粹,結(jié)果婚禮上览效,老公的妹妹穿的比我還像新娘。我一直安慰自己球榆,他們只是感情好朽肥,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,500評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著持钉,像睡著了一般衡招。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上每强,一...
    開(kāi)封第一講書(shū)人閱讀 51,370評(píng)論 1 302
  • 那天始腾,我揣著相機(jī)與錄音,去河邊找鬼空执。 笑死浪箭,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的辨绊。 我是一名探鬼主播奶栖,決...
    沈念sama閱讀 40,193評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼门坷!你這毒婦竟也來(lái)了宣鄙?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,074評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤默蚌,失蹤者是張志新(化名)和其女友劉穎冻晤,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體绸吸,經(jīng)...
    沈念sama閱讀 45,505評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡鼻弧,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,722評(píng)論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了锦茁。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片攘轩。...
    茶點(diǎn)故事閱讀 39,841評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖码俩,靈堂內(nèi)的尸體忽然破棺而出撑刺,到底是詐尸還是另有隱情,我是刑警寧澤握玛,帶...
    沈念sama閱讀 35,569評(píng)論 5 345
  • 正文 年R本政府宣布够傍,位于F島的核電站甫菠,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏冕屯。R本人自食惡果不足惜寂诱,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,168評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望安聘。 院中可真熱鬧痰洒,春花似錦、人聲如沸浴韭。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,783評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)念颈。三九已至泉粉,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間榴芳,已是汗流浹背嗡靡。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,918評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留窟感,地道東北人讨彼。 一個(gè)月前我還...
    沈念sama閱讀 47,962評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像柿祈,于是被迫代替她去往敵國(guó)和親哈误。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,781評(píng)論 2 354

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