JVM學(xué)習(xí)(一):Java虛擬機(jī)和虛擬機(jī)內(nèi)存區(qū)域

為什么Java程序需要運(yùn)行在虛擬機(jī)上

因?yàn)镴ava在設(shè)計(jì)之初的跨平臺(tái)特性,我們知道Java程序是運(yùn)行在Java虛擬機(jī)上的。如果你要問為什么Java程序要運(yùn)行在虛擬機(jī)上,我可以反問你幾個(gè)問題。

為什么買來的電器插上電就能直接使用?你可能會(huì)說骂际,因?yàn)殡娛腔A(chǔ)設(shè)施。電源有統(tǒng)一的標(biāo)準(zhǔn)冈欢,電器有統(tǒng)一的標(biāo)準(zhǔn)歉铝,所以買來的電器插上電就能用。

不同的電器需要的電源標(biāo)準(zhǔn)不同(臺(tái)燈和電飯煲的功率)凑耻,為什么我們不能給不同的電器配置不同的電源呢太示?因?yàn)樘闊┝四停m然這樣我們能讓每個(gè)電器都達(dá)到最適應(yīng)的效率,但是代價(jià)未免太大了些类缤。想一想臼勉,別人需要用你家的電器時(shí)首先要先配一個(gè)合適的發(fā)電機(jī)。

所以電力基礎(chǔ)設(shè)施需要把不同的發(fā)電方式發(fā)出的電接入同一個(gè)電網(wǎng)餐弱, 電力公司負(fù)責(zé)調(diào)度分配電力宴霸,并且在使用的時(shí)候提供相同標(biāo)準(zhǔn)的輸出。雖然這個(gè)過程損失了一部分電力膏蚓,但是大大提高了我們使用電器的便利瓢谢。

那么回過頭來看Java虛擬機(jī)。為什么Java程序要運(yùn)行在虛擬機(jī)上驮瞧,這是因?yàn)槲覀冃枰獙?shí)現(xiàn)一次編譯到處運(yùn)行(統(tǒng)一的電源標(biāo)準(zhǔn))氓扛。那么為什么C++不是跨平臺(tái)的呢,因?yàn)镃++編譯時(shí)會(huì)轉(zhuǎn)換為與機(jī)器關(guān)聯(lián)的機(jī)器碼论笔,這導(dǎo)致了C++編譯的程序只能在特定的機(jī)器上運(yùn)行(類似于給不同的電器配置了不同的電源)幢尚。

Java的內(nèi)存區(qū)域

說回Java虛擬機(jī),我們知道C++程序員是需要手動(dòng)清理內(nèi)存的翅楼,Java程序不需要手動(dòng)清理,其內(nèi)存管理由虛擬機(jī)負(fù)責(zé)真慢。那么Java是如何管理內(nèi)存的呢毅臊?

Java虛擬機(jī)會(huì)把它管理的內(nèi)存劃分成幾個(gè)不同的數(shù)據(jù)區(qū)。如下圖所示:


image.png

1.程序計(jì)數(shù)器(PC寄存器)

程序計(jì)數(shù)器時(shí)當(dāng)前線程所執(zhí)行的字節(jié)碼的行號(hào)指示器黑界。因?yàn)镴ava虛擬機(jī)的多線程輪換是通過線程輪流切換分配處理器執(zhí)行時(shí)間來實(shí)現(xiàn)的管嬉,所以每個(gè)線程都會(huì)有一個(gè)程序計(jì)數(shù)器。

另外朗鸠,Java程序既有Java方法也有本地方法蚯撩。假如線程執(zhí)行的是Java方法,那么程序計(jì)數(shù)器記錄的是當(dāng)前執(zhí)行的字節(jié)碼指令的地址烛占。如果是本地方法胎挎,則計(jì)數(shù)器值為空。此區(qū)域是Java虛擬機(jī)規(guī)范中唯一的沒有規(guī)定OutOfMemoryError的區(qū)域忆家。

2.Java虛擬機(jī)棧

Java虛擬機(jī)棧也是線程私有的犹菇,它的生命周期與線程相同。虛擬機(jī)棧描述的是Java方法執(zhí)行的內(nèi)存模型:每個(gè)方法在執(zhí)行的同時(shí)都會(huì)創(chuàng)建一個(gè)棧幀用于存儲(chǔ)局部變量表芽卿、操作數(shù)棧揭芍、動(dòng)態(tài)鏈表、方法出口等信息卸例。當(dāng)退出當(dāng)前執(zhí)行的方法時(shí)称杨,不管是正常返回還是異常返回肌毅,Java虛擬機(jī)均會(huì)彈出當(dāng)前線程棧幀并舍棄。

3.本地方法棧

本地方法棧跟Java虛擬機(jī)棧的作用基本相同姑原,本地方法棧其實(shí)是Native方法執(zhí)行過程中存儲(chǔ)方法的數(shù)據(jù)結(jié)構(gòu)的椥空間。

4.Java堆

Java堆(Java Heap)是Java虛擬機(jī)管理內(nèi)存中最大的一塊页衙。Java堆是被所有線程共享的一塊內(nèi)存區(qū)域摊滔,在虛擬機(jī)啟動(dòng)時(shí)創(chuàng)建。此內(nèi)存區(qū)域的唯一目的時(shí)存放對(duì)象實(shí)例店乐。另外Java堆也是垃圾回收器管理的主要區(qū)域艰躺,因此很多時(shí)候也成為「GC堆」。

5.方法區(qū)

方法區(qū)和Java堆一樣眨八,是各個(gè)線程共享的內(nèi)存區(qū)域腺兴,它是用來存儲(chǔ)已被虛擬機(jī)加載的類信息、常量廉侧、靜態(tài)變量页响、即時(shí)編譯器編譯后的代碼等數(shù)據(jù)。

其中常量會(huì)單獨(dú)放置在運(yùn)行時(shí)常量池(JDK8中放到了堆中)中段誊。運(yùn)行時(shí)常量池具備動(dòng)態(tài)性闰蚕,也就是在程序運(yùn)行期間也可以將新的常量放入池中,這種特性使用較多的事String類的intern()方法连舍。

6.直接內(nèi)存

直接內(nèi)存不是虛擬機(jī)運(yùn)行時(shí)數(shù)據(jù)區(qū)的一部分没陡,也不是Java虛擬機(jī)規(guī)范中定義的內(nèi)存區(qū)域。但是這部分內(nèi)存的頻繁使用也可能導(dǎo)致OutOfMemoryError異常出現(xiàn)索赏。

JDK 1.4中新加入了NIO(New Input/Output)類盼玄,引入了一種基于通道與緩沖區(qū)的I/O方式,它可以使用本地函數(shù)庫直接分配堆外內(nèi)存潜腻,然后通過一個(gè)存儲(chǔ)在Java堆中的DirectByteBuffer對(duì)象作為這塊內(nèi)存的引用進(jìn)行操作埃儿。在一些常見中這種操作能顯著提高性能。

總結(jié)

本篇我們了解了為什么Java虛擬機(jī)需要運(yùn)行在虛擬機(jī)上融涣,用了一個(gè)電源和電器的例子童番。Java虛擬機(jī)將內(nèi)存分成兩種,線程共享和線程獨(dú)占內(nèi)存區(qū)域威鹿。其中線程獨(dú)占的區(qū)域有程序計(jì)數(shù)器妓盲、Java虛擬機(jī)棧、本地方法棧专普。線程共享區(qū)域有Java堆悯衬、方法區(qū)(包括運(yùn)行時(shí)常量池)。在Java虛擬機(jī)運(yùn)行時(shí)數(shù)據(jù)區(qū)之外還有直接內(nèi)存,此區(qū)域可以使用堆外內(nèi)存來提升I/O的速度筋粗。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末策橘,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子娜亿,更是在濱河造成了極大的恐慌丽已,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,858評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件买决,死亡現(xiàn)場(chǎng)離奇詭異沛婴,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)督赤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門嘁灯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人躲舌,你說我怎么就攤上這事丑婿。” “怎么了没卸?”我有些...
    開封第一講書人閱讀 165,282評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵羹奉,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我约计,道長(zhǎng)诀拭,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,842評(píng)論 1 295
  • 正文 為了忘掉前任煤蚌,我火速辦了婚禮耕挨,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘铺然。我一直安慰自己,他們只是感情好酒甸,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評(píng)論 6 392
  • 文/花漫 我一把揭開白布魄健。 她就那樣靜靜地躺著,像睡著了一般插勤。 火紅的嫁衣襯著肌膚如雪沽瘦。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,679評(píng)論 1 305
  • 那天农尖,我揣著相機(jī)與錄音析恋,去河邊找鬼。 笑死盛卡,一個(gè)胖子當(dāng)著我的面吹牛助隧,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播滑沧,決...
    沈念sama閱讀 40,406評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼并村,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼巍实!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起哩牍,我...
    開封第一講書人閱讀 39,311評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤棚潦,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后膝昆,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體丸边,經(jīng)...
    沈念sama閱讀 45,767評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年荚孵,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了妹窖。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,090評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡处窥,死狀恐怖嘱吗,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情滔驾,我是刑警寧澤谒麦,帶...
    沈念sama閱讀 35,785評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站哆致,受9級(jí)特大地震影響绕德,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜摊阀,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評(píng)論 3 331
  • 文/蒙蒙 一耻蛇、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧胞此,春花似錦臣咖、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至酣胀,卻和暖如春刁赦,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背闻镶。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評(píng)論 1 271
  • 我被黑心中介騙來泰國打工甚脉, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人铆农。 一個(gè)月前我還...
    沈念sama閱讀 48,298評(píng)論 3 372
  • 正文 我出身青樓牺氨,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子波闹,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評(píng)論 2 355

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