java虛擬機JVM內(nèi)存組成結(jié)構(gòu)

1.JVM

JVM是Java Virtual Machine(Java虛擬機)的縮寫酣栈,JVM是一種用于計算設(shè)備的規(guī)范,它是一個虛構(gòu)出來的計算機蝠嘉,是通過在實際的計算機上仿真模擬各種計算機功能來實現(xiàn)的灯萍。
Java語言的一個非常重要的特點就是與平臺的無關(guān)性。而使用Java虛擬機就是實現(xiàn)這一特點的關(guān)鍵端铛。

2.JVM內(nèi)存模型

jvm內(nèi)存結(jié)構(gòu)
PC程序計數(shù)器

記錄正在執(zhí)行的虛擬機字節(jié)碼指令的地址泣矛,當(dāng)線程在執(zhí)行的是 Native 方法(調(diào)用本地操作系統(tǒng)方法)時,該計數(shù)器的值為空禾蚕。另外您朽,該內(nèi)存區(qū)域是唯一一個在 Java 虛擬機規(guī)范中么有規(guī)定任何 OOM(內(nèi)存溢出:OutOfMemoryError)情況的區(qū)域。

Java虛擬機棧

每個 Java 方法在執(zhí)行的同時會創(chuàng)建一個棧幀用于存儲局部變量表换淆、操作數(shù)棧哗总、動態(tài)連接几颜、方法返回地址和一些額外的附加信息。從方法調(diào)用直至執(zhí)行完成的過程讯屈,對應(yīng)著一個棧幀在 Java 虛擬機棧中入棧和出棧的過程蛋哭。
可以通過 -Xss 這個虛擬機參數(shù)來指定每個線程的 Java 虛擬機棧內(nèi)存大小,在 JDK 1.4 中默認(rèn)為 256K涮母,而在 JDK 1.5+ 默認(rèn)為 1M谆趾。

  • 局部變量表 是一組變量值存儲空間,用于存放方法參數(shù)和方法內(nèi)部定義的局部變量叛本,其中存放的數(shù)據(jù)的類型是編譯期可知的各種基本數(shù)據(jù)類型沪蓬、對象引用(reference)和 returnAddress 類型(它指向了一條字節(jié)碼指令的地址)。
  • 操作數(shù)棧又常被稱為操作棧炮赦,操作數(shù)棧的最大深度也是在編譯的時候就確定了怜跑。32 位數(shù)據(jù)類型所占的棧容量為 1,64 位數(shù)據(jù)類型所占的棧容量為 2。當(dāng)一個方法開始執(zhí)行時吠勘,它的操作棧是空的性芬,在方法的執(zhí)行過程中,會有各種字節(jié)碼指令(比如:加操作剧防、賦值元算等)向操作棧中寫入和提取內(nèi)容植锉,也就是入棧和出棧操作。
  • 動態(tài)連接 每個棧幀都包含一個指向運行時常量池中該棧幀所屬方法的引用峭拘,持有這個引用是為了支持方法調(diào)用過程中的動態(tài)連接俊庇。Class 文件的常量池中存在有大量的符號引用,字節(jié)碼中的方法調(diào)用指令就以常量池中指向方法的符號引用為參數(shù)鸡挠。這些符號引用辉饱,一部分會在類加載階段或第一次使用的時候轉(zhuǎn)化為直接引用(如 final、static 域等)拣展,稱為靜態(tài)解析彭沼,另一部分將在每一次的運行期間轉(zhuǎn)化為直接引用,這部分稱為動態(tài)連接备埃。
  • 方法返回地址 當(dāng)一個方法被執(zhí)行后姓惑,有兩種方式退出該方法:執(zhí)行引擎遇到了任意一個方法返回的字節(jié)碼指令或遇到了異常,并且該異常沒有在方法體內(nèi)得到處理按脚。方法退出的過程實際上等同于把當(dāng)前棧幀出站于毙,因此退出時可能執(zhí)行的操作有:恢復(fù)上層方法的局部變量表和操作數(shù)棧,如果有返回值辅搬,則把它壓入調(diào)用者棧幀的操作數(shù)棧中唯沮,調(diào)整 PC 計數(shù)器的值以指向方法調(diào)用指令后面的一條指令。

該區(qū)域可能拋出以下異常:

當(dāng)線程請求的棧深度超過最大值,會拋出 StackOverflowError 異常介蛉;
棧進行動態(tài)擴展時如果無法申請到足夠內(nèi)存夯缺,會拋出 OutOfMemoryError 異常。

本地方法棧

本地方法棧與 Java 虛擬機棧類似甘耿,只不過本地方法棧是為本地方法服務(wù)。

所有對象都在這里分配內(nèi)存竿滨,是垃圾收集的主要區(qū)域佳恬。堆分為新生代(Young Generation)和老年代(Old Generation)。新生代又可分為伊甸園區(qū)(Eden space)和兩個幸存者區(qū)(Survivor pace)于游。
可以通過 -Xms 和 -Xmx 這兩個虛擬機參數(shù)來指定一個程序的堆內(nèi)存大小毁葱,第一個參數(shù)設(shè)置初始值,第二個參數(shù)設(shè)置最大值贰剥。

方法區(qū)

用于存放已被加載的類信息倾剿、常量、靜態(tài)變量蚌成、即時編譯器JIT編譯后的代碼等數(shù)據(jù)前痘。對這塊區(qū)域進行垃圾回收的主要目標(biāo)是對常量池的回收和對類的卸載,但是一般比較難實現(xiàn)担忧。
HotSpot 虛擬機把它當(dāng)成永久代來進行垃圾回收芹缔。但很難確定永久代的大小,因為它受到很多因素影響瓶盛,并且每次 Full GC 之后永久代的大小都會改變最欠,所以經(jīng)常會拋出 OutOfMemoryError 異常。為了更容易管理方法區(qū)惩猫,從 JDK 1.8 開始芝硬,移除永久代,并把方法區(qū)移至元空間轧房,它位于本地內(nèi)存中拌阴,而不是虛擬機內(nèi)存中。方法區(qū)是一個 JVM 規(guī)范锯厢,永久代與元空間都是其一種實現(xiàn)方式皮官。
-XX:PermSize設(shè)置永久代初始大小,-XX:MaxPermSize設(shè)置永久代最大值实辑。

針對HotSpot 虛擬機
jdk1.6及之前: 有永久代捺氢, 方法區(qū)的數(shù)據(jù)存放在永久代中
jdk1.7: 有永久代,靜態(tài)變量和常量池存放在堆中;其它剩下的存放在永久代中
jdk1.8及之后: 無永久代剪撬,靜態(tài)變量和常量池存放在堆中摄乒;有元空間 ,儲存元信息等數(shù)據(jù)

運行時常量池

運行時常量池是方法區(qū)的一部分。Class 文件中的常量池(編譯器生成的字面量和符號引用)會在類加載后被放入這個區(qū)域馍佑。除了在編譯期生成的常量斋否,還允許動態(tài)生成,例如 String 類的 intern()拭荤。

  • 字面量 指字符串字面量和聲明為 final 的(基本數(shù)據(jù)類型)常量值茵臭,這些字符串字面量除了類中所有雙引號括起來的字符串(包括方法體內(nèi)的),還包括所有用到的類名舅世、方法的名字和這些類與方法的描述符旦委、字段(成員變量)的名稱和描述符、聲明為final的成員變量雏亚。這些都在常量池的表中缨硝。
  • 符號引用 指指向表中的這些字面量的引用,包括類和接口的全限定名罢低、字段的名稱和描述符查辩、方法的名稱和描述符。只不過是以一組符號來描述所引用的目標(biāo)网持,和內(nèi)存并無關(guān)宜岛,所以稱為符號引用,直接指向內(nèi)存中某一地址的引用稱為直接引用翎碑。
直接內(nèi)存

直接內(nèi)存并不是虛擬機運行時數(shù)據(jù)區(qū)的一部分谬返,也不是 Java 虛擬機規(guī)范中定義的內(nèi)存區(qū)域,它直接從操作系統(tǒng)中分配日杈,因此不受 Java 堆大小的限制遣铝。
在 JDK 1.4 中新引入了 NIO 類,它可以使用 Native 函數(shù)庫直接分配堆外內(nèi)存莉擒,然后通過 Java 堆里的 DirectByteBuffer 對象作為這塊內(nèi)存的引用進行操作酿炸。這樣能在一些場景中顯著提高性能,因為避免了在堆內(nèi)存和堆外內(nèi)存來回拷貝數(shù)據(jù)涨冀。

參考資料
周志明. 深入理解 Java 虛擬機 [M]. 機械工業(yè)出版社, 2011.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末填硕,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子鹿鳖,更是在濱河造成了極大的恐慌扁眯,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件翅帜,死亡現(xiàn)場離奇詭異姻檀,居然都是意外死亡,警方通過查閱死者的電腦和手機涝滴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進店門绣版,熙熙樓的掌柜王于貴愁眉苦臉地迎上來胶台,“玉大人,你說我怎么就攤上這事杂抽≌┗#” “怎么了?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵缩麸,是天一觀的道長铸磅。 經(jīng)常有香客問我,道長杭朱,這世上最難降的妖魔是什么愚屁? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮痕檬,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘送浊。我一直安慰自己梦谜,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布袭景。 她就那樣靜靜地躺著唁桩,像睡著了一般。 火紅的嫁衣襯著肌膚如雪耸棒。 梳的紋絲不亂的頭發(fā)上荒澡,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天,我揣著相機與錄音与殃,去河邊找鬼单山。 笑死,一個胖子當(dāng)著我的面吹牛幅疼,可吹牛的內(nèi)容都是我干的米奸。 我是一名探鬼主播,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼爽篷,長吁一口氣:“原來是場噩夢啊……” “哼悴晰!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起逐工,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤铡溪,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后泪喊,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體棕硫,經(jīng)...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年窘俺,在試婚紗的時候發(fā)現(xiàn)自己被綠了饲帅。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片复凳。...
    茶點故事閱讀 40,090評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖灶泵,靈堂內(nèi)的尸體忽然破棺而出育八,到底是詐尸還是另有隱情,我是刑警寧澤赦邻,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布髓棋,位于F島的核電站,受9級特大地震影響惶洲,放射性物質(zhì)發(fā)生泄漏按声。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一恬吕、第九天 我趴在偏房一處隱蔽的房頂上張望签则。 院中可真熱鬧,春花似錦铐料、人聲如沸渐裂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽柒凉。三九已至,卻和暖如春篓跛,著一層夾襖步出監(jiān)牢的瞬間膝捞,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工愧沟, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留蔬咬,地道東北人。 一個月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓沐寺,卻偏偏與公主長得像计盒,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子芽丹,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,033評論 2 355