Java運行時數(shù)據(jù)區(qū)詳解

Java虛擬機在執(zhí)行java程序的過程中會把它所管理的內(nèi)存劃分為若干個不同的數(shù)據(jù)區(qū)域.根據(jù) <<java虛擬機規(guī)范>> 中的規(guī)定,將內(nèi)存區(qū)域劃分為 程序計數(shù)器(Program Counter Register),虛擬機棧(VM Stack),本地方法棧(Native Method Stack),方法區(qū)(Method Area)堆(Heap)五大區(qū)域.

運行時內(nèi)存區(qū)域

程序計數(shù)器(Program Counter Register)

程序計數(shù)器是一塊很小的內(nèi)存區(qū)域,可以當成當前線程所執(zhí)行的字節(jié)碼的行號指示器.java解釋器通過改變計數(shù)器值來選取下一條指令.分治,循環(huán),跳轉(zhuǎn),異常處理,線程恢復(fù)等需要依賴計數(shù)器完成

特點:

  1. 每一個線程都有一個獨立的程序計數(shù)器,互不影響.(線程私有)
  2. 線程執(zhí)行Java方法,計數(shù)器記錄的是正在執(zhí)行的虛擬機字節(jié)碼指令的地址.
  3. 線程執(zhí)行Native方法,計數(shù)器則為空.
  4. 唯一一個沒有定義 OutOfMemoryError的區(qū)域.

虛擬機棧(VM Stack)

虛擬機棧它的棧元素是一種叫做棧幀(Stack Frame)的結(jié)構(gòu).每一個棧幀都包括了 局部變量表(Local Variable Table),操作數(shù)棧(Operand Stack),動態(tài)鏈接(Dynamic Linking),方法返回地址(Return Address)和一些額外信息.
棧幀是用于支持虛擬機進行方法調(diào)用和方法執(zhí)行的數(shù)據(jù)結(jié)構(gòu),每一個方法從調(diào)用開始至執(zhí)行完成的過程,都對應(yīng)著一個棧幀在虛擬機棧里面從入棧到出棧的過程.

棧幀結(jié)構(gòu)

特點:

  1. Java虛擬機棧是線程私有的,生命周期與線程一致
  2. 局部變量表所需的內(nèi)存空間在編譯期間確定,并完成分配.
  3. 在方法運行期間不會改變局部變量表的大小.
  4. 如果請求的棧深度大于虛擬機允許的深度,拋出StackOverflowError.
  5. 虛擬機棧擴展時無法申請足夠的內(nèi)存,拋出OutOfMemoryError

本地方法棧(Native Method Stack)

功能與虛擬機棧類似,java線程在調(diào)用本地方法時沃暗,該區(qū)用來存儲本地方法的局部變量表备燃,本地方法的操作數(shù)棧等等信息.區(qū)別在于虛擬機棧執(zhí)行的是java方法,
本地方法棧執(zhí)行的是native方法(c/c++方法).

java是高級編程語言剧蹂,當對一些底層的如操作系統(tǒng)或某些硬件交換信息時谭期,我們使用java來編程實現(xiàn)起來不容易入偷,再者使用java來編程效率也很低下.這時候就可以通過 JNI方式來調(diào)用 native方法來實現(xiàn).

本地方法棧與java棧

如果,展示了java與native方法交互的過程,java方法中調(diào)用了C語言方法,產(chǎn)生在本地方法棧中產(chǎn)生一個本地棧幀,這個C語言方法調(diào)用了另一個C語言方法,并且把結(jié)果回調(diào)回java方法中.

一個線程可能在整個生命周期中都執(zhí)行Java方法荆姆,操作他的Java棧肛走;或者他可能毫無障礙地在Java棧和本地方法棧之間跳轉(zhuǎn)忱嘹。

特點 :

  1. 線程私有,生命周期與線程一致
  2. 調(diào)用的是 c/c++方法(一般用于底層交互,或者性能優(yōu)化)
  3. 可拋出StackOverflowErrorOutOfMemoryError

java堆(Heap)

java虛擬機中最大的內(nèi)存區(qū)域,幾乎所有類實例和數(shù)組的內(nèi)存均從此處分配嘱腥。

  1. 線程共享
  2. 在 Java 虛擬機啟動時創(chuàng)建的
  3. GC管理的主要區(qū)域
  4. 可位于物理內(nèi)存不連續(xù)的空間.
  5. 可以是固定大小的,也可以是可擴展的.
  6. 在沒有內(nèi)存空間并且無法擴展時,拋出OutOfMemoryError

hotspot中的實現(xiàn)

在hotspot虛擬機中,從內(nèi)存回收的角度來看是采用 分代收集策略.將堆劃分為兩個不同的區(qū)域:
新生代(Young Gen)老年代(Old Gen).

堆的空間大小 = 新生代 + 老年代; 默認情況下,新生代和老年代的比例是 1:2;

新生代又被劃分為Eden,From SurvivorTo Survivor三個區(qū)域;大小比例為 8:1:1
由于新生代采用復(fù)制算法來管理空間,因此,無論什么時候,總是有一塊 Survivor 區(qū)域是空閑著的拘悦。
新生代實際可用的內(nèi)存空間為90%的新生代空間齿兔。

方法區(qū)(Mthod Area)

方法區(qū)中,存儲著已加載的類信息,常量,靜態(tài)變量,即時編譯后的代碼等數(shù)據(jù).
其中類相關(guān)的信息,如類名,訪問修飾符,常量池,字段描述,方法描述等.
方法區(qū)邏輯上屬于堆的一部分,但是為了與堆進行區(qū)分,通常又叫“非堆”分苇。
方法區(qū)的數(shù)據(jù)是線程共享的.

為何叫方法區(qū)? 方法區(qū)中除了包括“已加載的類的基本信息添诉、常量、靜態(tài)變量等”外组砚,還包括編譯器編譯后的代碼吻商,而且這應(yīng)該是方法區(qū)中主要的一部分掏颊,這可能是為何把這部分內(nèi)存成為方法區(qū)的原因.

注釋 : 類的對象和實例對象存放在 java堆中, 類的元數(shù)據(jù)存放在 方法區(qū)中.

不同jdk(hotspot)版本,方法區(qū)數(shù)據(jù)的變化

JDK 1.6以及之前,方法區(qū)的實現(xiàn)為 永久代(Permanent Gen)的方式,目的是為了垃圾收集器能像管理java堆一樣管理這部分內(nèi)存.垃圾回收目標是針對常量池的回收和對類型的卸載.

JDK 1.7中糟红,存儲在永久代的部分數(shù)據(jù)就已經(jīng)轉(zhuǎn)移到Java Heap或者Native Heap。但永久代仍存在于JDK 1.7中乌叶,并沒有完全移除盆偿,如符號引用(Symbols)轉(zhuǎn)移到了native heap;字面量(interned strings)轉(zhuǎn)移到了Java heap准浴;類的靜態(tài)變量(class statics)存放于定義類型的class對象中,存放在Java heap中.

JDK 1.8中, 完全移除了永久代,取而代之的實現(xiàn)方式成為元空間(Metaspace),將類元數(shù)據(jù)放到本地內(nèi)存中事扭,將字符常量池和靜態(tài)變量放到Java堆里。虛擬機會為類的元數(shù)據(jù)明確分配和釋放本地內(nèi)存乐横。

元空間的本質(zhì)和永久代類似求橄,都是對JVM規(guī)范中方法區(qū)的實現(xiàn)。不過元空間與永久代之間的最大區(qū)別在于:元空間并不在虛擬機中葡公,而是使用本地內(nèi)存罐农。

Native memory:本地內(nèi)存,也稱為C-Heap催什,是供JVM自身進程使用的涵亏。當Java Heap空間不足時會觸發(fā)GC,但Native memory空間不夠卻不會觸發(fā)GC蒲凶。即GC不管理元空間(Metaspace)的內(nèi)存.

為什么移除永久代气筋?

  1. 字符串存在永久代中,容易出現(xiàn)性能問題和內(nèi)存溢出旋圆。
  2. 永久代大小不容易確定宠默,PermSize指定太小容易造成永久代OOM
  3. 永久代會為 GC 帶來不必要的復(fù)雜度,并且回收效率偏低灵巧。
  4. Oracle 可能會將HotSpot 與 JRockit 合二為一搀矫。

參考

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市孩等,隨后出現(xiàn)的幾起案子艾君,更是在濱河造成了極大的恐慌,老刑警劉巖肄方,帶你破解...
    沈念sama閱讀 219,366評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件冰垄,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機虹茶,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評論 3 395
  • 文/潘曉璐 我一進店門逝薪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人蝴罪,你說我怎么就攤上這事董济。” “怎么了要门?”我有些...
    開封第一講書人閱讀 165,689評論 0 356
  • 文/不壞的土叔 我叫張陵虏肾,是天一觀的道長。 經(jīng)常有香客問我欢搜,道長封豪,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,925評論 1 295
  • 正文 為了忘掉前任炒瘟,我火速辦了婚禮吹埠,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘疮装。我一直安慰自己缘琅,他們只是感情好,可當我...
    茶點故事閱讀 67,942評論 6 392
  • 文/花漫 我一把揭開白布廓推。 她就那樣靜靜地躺著刷袍,像睡著了一般。 火紅的嫁衣襯著肌膚如雪受啥。 梳的紋絲不亂的頭發(fā)上做个,一...
    開封第一講書人閱讀 51,727評論 1 305
  • 那天,我揣著相機與錄音滚局,去河邊找鬼居暖。 笑死,一個胖子當著我的面吹牛藤肢,可吹牛的內(nèi)容都是我干的太闺。 我是一名探鬼主播,決...
    沈念sama閱讀 40,447評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼嘁圈,長吁一口氣:“原來是場噩夢啊……” “哼省骂!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起最住,我...
    開封第一講書人閱讀 39,349評論 0 276
  • 序言:老撾萬榮一對情侶失蹤钞澳,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后涨缚,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體轧粟,經(jīng)...
    沈念sama閱讀 45,820評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,990評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了兰吟。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片通惫。...
    茶點故事閱讀 40,127評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖混蔼,靈堂內(nèi)的尸體忽然破棺而出履腋,到底是詐尸還是另有隱情,我是刑警寧澤惭嚣,帶...
    沈念sama閱讀 35,812評論 5 346
  • 正文 年R本政府宣布遵湖,位于F島的核電站,受9級特大地震影響料按,放射性物質(zhì)發(fā)生泄漏奄侠。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,471評論 3 331
  • 文/蒙蒙 一载矿、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧烹卒,春花似錦闷盔、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,017評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至藐吮,卻和暖如春溺拱,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背谣辞。 一陣腳步聲響...
    開封第一講書人閱讀 33,142評論 1 272
  • 我被黑心中介騙來泰國打工迫摔, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人泥从。 一個月前我還...
    沈念sama閱讀 48,388評論 3 373
  • 正文 我出身青樓句占,卻偏偏與公主長得像,于是被迫代替她去往敵國和親躯嫉。 傳聞我的和親對象是個殘疾皇子纱烘,可洞房花燭夜當晚...
    茶點故事閱讀 45,066評論 2 355

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