【JAVA提升】- JVM內存結構分析

1 java內存結構圖

理解學習java虛擬機內存結構,能夠幫助我們更加清楚知道java程序在操作的時候如果存儲數據,是java虛擬機的性能優化(GC調優)的基礎。

談到JVM內存結構,當然少不了這個經典的結構圖

jvm-structure.jpg

上圖清晰描述了JVM的內存結構,分別有以下幾個部分組成

  • 堆(Heap):線程共享。所有的對象實例以及數組都要在堆上分配。回收器主要管理的對象。
  • 方法區(Method Area):線程共享。存儲類信息、常量、靜態變量、即時編譯器編譯后的代碼。
  • 方法棧(JVM Stack):線程私有。存儲局部變量表、操作棧、動態鏈接、方法出口,對象指針。
  • 本地方法棧(Native Method Stack):線程私有。為虛擬機使用到的Native 方法服務。如Java使用c或者c++編寫的接口服務時,代碼在此區運行。
  • 程序計數器(Program Counter Register):線程私有。有些文章也翻譯成PC寄存器(PC Register),同一個東西。它可以看作是當前線程所執行的字節碼的行號指示器。指向下一條要執行的指令。

2 java內存模塊分析

以下這個圖,幫忙理解jvm的一些參數控制

jvm.jpg

2.1 堆

堆的作用是存放對象實例和數組。從結構上來分,可以分為新生代和老年代。而新生代又可以分為Eden 空間、From Survivor 空間(s0)、To Survivor 空間(s1)。 所有新生成的對象首先都是放在新生代的。需要注意,Survivor的兩個區是對稱的,沒先后關系,所以同一個區中可能同時存在從Eden復制過來的對象,和從前一個Survivor復制過來的對象。而且,Survivor區總有一個是空的。

  • 新生代: 新生代由 Eden 與 Survivor Space(S0,S1)構成,大小通過-Xmn參數指定,Eden 與 Survivor Space 的內存大小比例默認為8:1,可以通過-XX:SurvivorRatio 參數指定,比如新生代為10M 時,Eden分配8M,S0和S1各分配1M。

  • Eden: 希臘語,意思為伊甸園,在圣經中,伊甸園含有樂園的意思,根據《舊約·創世紀》記載,上帝耶和華照自己的形像造了第一個男人亞當,再用亞當的一個肋骨創造了一個女人夏娃,并安置他們住在了伊甸園。
    大多數情況下,對象在Eden中分配,當Eden沒有足夠空間時,會觸發一次Minor GC,虛擬機提供了-XX:+PrintGCDetails/-Xlog:gc*參數,告訴虛擬機在發生垃圾回收時打印內存回收日志。

  • Survivor: 意思為幸存者,是新生代和老年代的緩沖區域。當新生代發生GC(Minor GC)時,會將存活的對象移動到S0內存區域,并清空Eden區域,當再次發生Minor GC時,將Eden和S0中存活的對象移動到S1內存區域。
    存活對象會反復在S0和S1之間移動,當對象從Eden移動到Survivor或者在Survivor之間移動時,對象的GC年齡自動累加,當GC年齡超過默認閾值15時,會將該對象移動到老年代,可以通過參數-XX:MaxTenuringThreshold 對GC年齡的閾值進行設置。

  • 老年代: 老年代的空間大小即-Xmx 與-Xmn 兩個參數之差,用于存放經過幾次Minor GC之后依舊存活的對象。當老年代的空間不足時,會觸發Major GC/Full GC,速度一般比Minor GC慢10倍以上。

控制參數

  • -Xms設置堆的初始空間大小。
  • -Xmx設置堆的最大空間大小。
  • -Xmn控制新生代大小。(jdk1.4之后使用)
  • -XX:NewSize設置新生代最小空間大小
  • -XX:MaxNewSize設置新生代最小空間大小,
  • -XX:NewRatio 老年代:年輕代的比例, 如2 代表 young:old = 1:2
  • -XX:SurvivorRatio Eden:Survivor的比例 如8 代表 eden:s0:s1 = 8:1:1

垃圾回收

此區域是垃圾回收的主要操作區域。

異常情況

如果在堆中沒有內存完成實例分配,并且堆也無法再擴展時,將會拋出OutOfMemoryError 異常

2.2 方法區

方法區(Method Area)與Java 堆一樣,是各個線程共享的內存區域,它用于存儲已被虛擬機加載的類信息、常量、靜態變量、即時編譯器編譯后的代碼等數據。雖然Java 虛擬機規范把方法區描述為堆的一個邏輯部分,但是它卻有一個別名叫做Non-Heap(非堆),目的應該是與Java 堆區分開來。

很多人愿意把方法區稱為“永久代”(Permanent Generation),本質上兩者并不等價,僅僅是因為HotSpot虛擬機的設計團隊選擇把GC 分代收集擴展至方法區,或者說使用永久代來實現方法區而已。對于其他虛擬機(如BEA JRockit、IBM J9 等)來說是不存在永久代的概念的。在Java8中永生代徹底消失了。

控制參數

  • -XX:PermSize 設置最小空間

  • -XX:MaxPermSize 設置最大空間。

  • -XX:MetaspaceSize=8m (1.8之后去掉方法區,使用元數據區)

  • -XX:MaxMetaspaceSize=80m(1.8之后去掉方法區,使用元數據區)

  • -XX:CompressedClassSpaceSize(1.8之后去掉方法區,使用元數據區)

在JDK8后,方法區被移除了,引入了新的空間Metaspace來存放類的信息。

Metaspace不在虛擬機中,而是使用本地內存,這樣困擾我們的PermenGen的內存就不存在了,其上限變成了物理內存,當然可以通過參數進行設置。

-XX:MetaspaceSize=8m -XX:MaxMetaspaceSize=80m

那么曾經在其中的常量池被轉移到哪里了?答案是在堆中。

關于PermGen 和 metaspace, 請一定看看,請參考 深入理解堆外內存 Metaspace
聊聊jvm的PermGen與Metaspace

垃圾回收

對此區域會涉及但是很少進行垃圾回收。這個區域的內存回收目標主要是針對常量池的回收和對類型的卸載,一般來說這個區域的回收“成績”比較難以令人滿意。

異常情況

根據Java 虛擬機規范的規定, 當方法區無法滿足內存分配需求時,將拋出OutOfMemoryError。

2.3 方法棧

每個線程會有一個私有的棧。每個線程中方法的調用又會在本棧中創建一個棧幀。在方法棧中會存放編譯期可知的各種基本數據類型(boolean、byte、char、short、int、float、long、double)、對象引用(reference 類型,它不等同于對象本身。局部變量表所需的內存空間在編譯期間完成分配,當進入一個方法時,這個方法需要在幀中分配多大的局部變量空間是完全確定的,在方法運行期間不會改變局部變量表的大小。

控制參數

-Xss控制每個線程棧的大小。

異常情況

在Java 虛擬機規范中,對這個區域規定了兩種異常狀況:

  • StackOverflowError: 異常線程請求的棧深度大于虛擬機所允許的深度時拋出;
  • OutOfMemoryError 異常: 虛擬機棧可以動態擴展,當擴展時無法申請到足夠的內存時會拋出。

2.4 本地方法棧

本地方法棧(Native Method Stacks)與虛擬機棧所發揮的作用是非常相似的,其區別不過是虛擬機棧為虛擬機執行Java 方法(也就是字節碼)服務,而本地方法棧則是為虛擬機使用到的Native 方法服務。

控制參數

在Sun JDK中本地方法棧和方法棧是同一個,因此也可以用-Xss控制每個線程的大小。

異常情況

與虛擬機棧一樣,本地方法棧區域也會拋出StackOverflowError 和OutOfMemoryError異常。

2.5 程序計數器

它的作用可以看做是當前線程所執行的字節碼的行號指示器。

異常情況

此內存區域是唯一一個在Java 虛擬機規范中沒有規定任何OutOfMemoryError 情況的區域。


參考鏈接

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,885評論 6 541
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,312評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,993評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,667評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,410評論 6 411
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,778評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,775評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,955評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,521評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,266評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,468評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,998評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,696評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,095評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,385評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,193評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,431評論 2 378

推薦閱讀更多精彩內容