java提供的自動垃圾收集機制大大提高了程序員的開發(fā)效率。
但是自動垃圾收集不是萬能的,明確jvm的內(nèi)存結(jié)構(gòu),工作機制是設(shè)計高擴展應用的基礎(chǔ)。
也是診斷jvm運行時問題的必備技能。
我是李福春,我在準備面試,今天的題目是:
jvm的內(nèi)存結(jié)構(gòu)是怎樣的?哪些區(qū)域容易發(fā)生OOM?
答:分3部分回答,具體如上圖所示:
1,線程私有的:分為虛擬機棧,本地方法棧,程序計數(shù)器;
2,線程共享的:分為堆,方法區(qū)(元數(shù)據(jù),常量池)
3,jvm之外的:分為直接內(nèi)存和 code cache ;
然后為每個部分分別展開說明一下。
虛擬機棧: 每個線程的一次方法執(zhí)行都對應一個虛擬機棧的棧幀,包含方法入?yún)ⅲ僮鲾?shù),動態(tài)鏈接,方法正常結(jié)束或者異常退出的定義
本地方法棧:線程調(diào)用本地方法對應一個本地方法棧,跟虛擬機棧在同一塊區(qū)域;
程序計數(shù)器:記錄線程正在執(zhí)行的jvm指令地址
堆:java的對象生成區(qū)域,所有的線程共享,是垃圾收集的重點照顧區(qū)域,可以進一步分為新聲代,老年代,xms設(shè)置的是堆大小;
方法區(qū):放了java的類對象定義,以及常量池;
發(fā)生OOM的區(qū)域如圖所示,除了程序計數(shù)器部分,其它的部分都可能直接或者間接的引起OOM(OutOfMemoryError);
分別說明如下:
1,堆, 如內(nèi)存泄露,堆大小設(shè)置不合理,運行期間對象的回收不及時,都可能引起堆的OOM;
2,棧:棧的無限遞歸調(diào)用直接導致StackOverFlowError,jvm會重新擴展??臻g,引起OOM;
3,方法區(qū):老版本常量池的回收非常不積極;比如字符串緩存堆積;
4,給的元數(shù)據(jù)空間不足以及直接內(nèi)存不足也是可能引起OOM;
本節(jié)畫了java的jvm的內(nèi)存結(jié)構(gòu)圖,分別分析了每一塊的用途;
然后針對每一塊可能產(chǎn)生OOM的原因做了分類。
原創(chuàng)不易,轉(zhuǎn)載請注明出處。