JVM系列(三)內(nèi)存劃分

? ? ? ?我們的java代碼經(jīng)過了類加載到了JVM運(yùn)行時(shí)候缅叠,就需要使用到多塊內(nèi)存空間,不同的空間存放不同的數(shù)據(jù),配合代碼流程,才能讓程真正運(yùn)行起來钓账。

? ? ? JVM內(nèi)存劃分在JDK1.8之后和之前是略有不同主要是將方法區(qū)調(diào)整為了元空間

JDK1.8之前:

JDK1.8之后:

? ? ? ?圖上線程區(qū)的域的數(shù)據(jù)是私有的却盘,其他區(qū)域的數(shù)據(jù)是共享的勃救。

? ? ? ?內(nèi)存的劃分其實(shí)就是為了我們的代碼在運(yùn)行的過程中根據(jù)不同的需要來使用的迈套,具體有以下:

(1)方法區(qū)(存放類)

? ? ? ? 方法區(qū)與堆一樣,是各個(gè)線程共享內(nèi)存區(qū)域,方法區(qū)也被稱為非堆或者永久代侵佃。方法區(qū)在JDK1.8以前的版本麻昼,代表JVM的一塊區(qū)域。主要存放.class文件里加載進(jìn)來的類馋辈,同時(shí)也會(huì)存放一些類似常量池的東西在這個(gè)區(qū)域抚芦。 但是在JDK1.8之后這里就改名為MetaSpace(元空間),主要還是用來存放各種類相關(guān)信息迈螟。

? ? ? ? 整個(gè)永久代有一個(gè)JVM本身設(shè)置的固定大小上限燕垃,無法進(jìn)行調(diào)整。但是1.8后元空間使用的是直接內(nèi)存井联,受本機(jī)內(nèi)存的限制卜壕,內(nèi)存溢出的幾率比永久代小了很多

(2)運(yùn)行時(shí)常量

? ? ? .class文件中除了存放類版本、字段烙常、方法轴捎、接口等描述信息外、還有常量池(用于存放編譯期生成的各種字面量和符號(hào)引用)蚕脏,?運(yùn)行時(shí)常量是方法區(qū)的一部分侦副,受到方法區(qū)內(nèi)存限制,當(dāng)常量無法在申請(qǐng)到內(nèi)存空間時(shí)候會(huì)拋出OutofMemoryError異常驼鞭。在JDK1.7之前運(yùn)行時(shí)常量池邏輯包含字符串常量池秦驯,JDK1.7字符串常量池被從方法區(qū)拿到了堆中。運(yùn)行時(shí)常量池還在方法區(qū)挣棕,JDK1.8移除了永久代译隘,運(yùn)行時(shí)常量轉(zhuǎn)移到元空間中

(3)程序計(jì)數(shù)器(執(zhí)行代碼指令)

? ? ? ?我們所開發(fā)的代碼是.java文件是面向開發(fā)人員的,但是計(jì)算機(jī)是無法讀懂的洛心,所以就需要編譯為.class字節(jié)碼文件固耘,字節(jié)碼才是計(jì)算機(jī)可以理解的文件。字節(jié)碼的指令會(huì)讓程序執(zhí)行各種操作词身。

? ? ? ? 程序計(jì)數(shù)器可以看作是當(dāng)前線程所執(zhí)行字節(jié)碼指令的行號(hào)指示器厅目,主要有兩個(gè)作用

1.字節(jié)碼解釋器通過改變程序計(jì)數(shù)器,來依次讀取需要執(zhí)行的指令法严,從而實(shí)現(xiàn)代碼的流程控制(順序執(zhí)行损敷、選擇、循環(huán)深啤、異常處理)

2.多線程的情況下拗馒,程序計(jì)數(shù)器用于記錄當(dāng)前線程執(zhí)行的位置,從而當(dāng)線程被切換回來也能知道上次運(yùn)行的位置墓塌。每條線程間的程序計(jì)數(shù)器是互不影響的瘟忱,獨(dú)立存儲(chǔ)、也就是"線程私有"苫幢。

? ? ? ?程序計(jì)數(shù)器是唯一一個(gè)不會(huì)出現(xiàn)OutofMemoryError的內(nèi)存區(qū)域访诱,生命周期是從線程的創(chuàng)建至線程的銷毀。

(4)JAVA虛擬機(jī)棧

? ? ? ?我們?cè)诜椒ㄖ薪?jīng)常會(huì)定義一些局部變量韩肝,就會(huì)保存在JAVA的虛擬機(jī)棧中触菜。JAVA虛擬機(jī)棧是由多個(gè)幀棧組成,如果線程執(zhí)行了一個(gè)方法哀峻,那么就會(huì)對(duì)這個(gè)方法調(diào)用涡相,創(chuàng)建一個(gè)對(duì)應(yīng)的幀棧都包含(局部變量表、操作數(shù)棧剩蟀、動(dòng)態(tài)鏈接催蝗、方法出口等信息)。每一次函數(shù)調(diào)用就會(huì)有一個(gè)對(duì)應(yīng)的幀棧被壓入JAVA棧育特,每個(gè)函數(shù)調(diào)用結(jié)束后就會(huì)有一個(gè)幀棧被彈出丙号,棧的順序是先進(jìn)后出

? ? ? ?JAVA虛擬機(jī)棧也是私有的,生命周期也是從線程的創(chuàng)建至線程的銷毀缰冤。虛擬機(jī)棧會(huì)出現(xiàn)兩種錯(cuò)誤:

1.StackOverFlowError: 如果虛擬棧的內(nèi)存大小不允許動(dòng)態(tài)擴(kuò)展犬缨,那么當(dāng)線程請(qǐng)求棧的深度大于java虛擬機(jī)棧的最大深度時(shí),會(huì)拋出該異常

2.OutofMemoryError: 虛擬機(jī)棧的內(nèi)存大小允許動(dòng)態(tài)擴(kuò)展棉浸,如果虛擬機(jī)在動(dòng)態(tài)擴(kuò)展棧時(shí)怀薛,無法申請(qǐng)到足夠的內(nèi)存空間,會(huì)拋出該異常

(5)本地方法棧

? ? ? ? 與JAVA虛擬機(jī)棧相似迷郑,區(qū)別:虛擬棧執(zhí)行JAVA的方法枝恋,而本地方法棧是為虛擬機(jī)使用到的Native方法服務(wù)(在HotSpot虛擬機(jī)中與JAVA虛擬機(jī)棧合二為一)。棧的順序是先進(jìn)后出嗡害,也會(huì)產(chǎn)生兩種異常

(6)堆

? ? ? ? JAVA的堆內(nèi)存是用來存放我們代碼中創(chuàng)建的各種對(duì)象鼓择,是所有線程共享的一塊區(qū)域。幾乎所有的對(duì)象實(shí)例以及數(shù)組都是在這里分配內(nèi)存就漾,但是隨著JIT動(dòng)態(tài)編譯技術(shù)的發(fā)展與逃逸分析技術(shù)的成熟呐能,從JDK1.7開始已經(jīng)默認(rèn)開啟了逃逸分析,如果某些方法的對(duì)象引用沒有被返回或者是未被使用(也就是未逃逸出去)抑堡,那么對(duì)象可以直接在棧上分配內(nèi)存摆出。堆的順序是先進(jìn)先出

? ? ? ?JAVA堆是垃圾回收的主要區(qū)域,因此也叫GC堆首妖。是最容易產(chǎn)生?OutOfMemoryError 異常偎漫,例如:

1.OutOfMemoryError: GC Overhead Limit Exceeded: 當(dāng)JVM花費(fèi)很長(zhǎng)的時(shí)間執(zhí)行垃圾回收,并且只能回收到很小的堆空間時(shí)有缆,就會(huì)引發(fā)此異常

2.java.lang.OutOfMemoryError: Java heap space: 如果在新建對(duì)象時(shí)象踊,堆內(nèi)存空間存放不下温亲,就會(huì)引發(fā)此異常(和配置的內(nèi)存大小有關(guān),與物理內(nèi)存無關(guān))

? ? ? ? 棧與堆都是JAVA用來存儲(chǔ)數(shù)據(jù)的地方杯矩。棧的優(yōu)勢(shì)為存儲(chǔ)比堆快栈虚,僅次于CPU中的寄存器,缺點(diǎn)是存在棧中的數(shù)據(jù)大小與生命期是確定的史隆,缺乏靈活性魂务。堆的優(yōu)勢(shì)可以動(dòng)態(tài)的分配內(nèi)存大小,生命期也是非固定的泌射,缺點(diǎn)是需要在運(yùn)行是進(jìn)行動(dòng)態(tài)分配粘姜,存取速度較慢

(7)直接內(nèi)存

? ? ? ?直接內(nèi)存并不是虛擬機(jī)運(yùn)行時(shí)數(shù)據(jù)區(qū)的一部分,也不是虛擬機(jī)的內(nèi)存區(qū)域熔酷,但是這部分內(nèi)存也被頻繁使用到孤紧,也會(huì)導(dǎo)致OutOfMemoryError異常。本地內(nèi)存不受java堆堆限制拒秘,但是會(huì)受到本機(jī)總內(nèi)存大小及處理器尋址空間限制

? ? ? ? ?在JDK1.4中加入的NIO(New Input/OutPut)類坛芽,引入了一種基于渠道(channel)與緩沖區(qū)(Buffer)的I/O方式,它可以直接使用Native函數(shù)庫直接分配堆外內(nèi)存翼抠,然后通過一個(gè)存儲(chǔ)在JAVA堆中的DirectByteBuffer對(duì)象作為這塊的內(nèi)存引用操作咙轩,這樣避免了在Java堆與Native堆來回的復(fù)制數(shù)據(jù),從而提高了性能

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末阴颖,一起剝皮案震驚了整個(gè)濱河市活喊,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌量愧,老刑警劉巖钾菊,帶你破解...
    沈念sama閱讀 219,039評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異偎肃,居然都是意外死亡煞烫,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門累颂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來滞详,“玉大人,你說我怎么就攤上這事紊馏×霞ⅲ” “怎么了?”我有些...
    開封第一講書人閱讀 165,417評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵朱监,是天一觀的道長(zhǎng)岸啡。 經(jīng)常有香客問我,道長(zhǎng)赫编,這世上最難降的妖魔是什么巡蘸? 我笑而不...
    開封第一講書人閱讀 58,868評(píng)論 1 295
  • 正文 為了忘掉前任奋隶,我火速辦了婚禮,結(jié)果婚禮上悦荒,老公的妹妹穿的比我還像新娘唯欣。我一直安慰自己,他們只是感情好逾冬,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,892評(píng)論 6 392
  • 文/花漫 我一把揭開白布黍聂。 她就那樣靜靜地躺著躺苦,像睡著了一般身腻。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上匹厘,一...
    開封第一講書人閱讀 51,692評(píng)論 1 305
  • 那天嘀趟,我揣著相機(jī)與錄音,去河邊找鬼愈诚。 笑死她按,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的炕柔。 我是一名探鬼主播酌泰,決...
    沈念sama閱讀 40,416評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼匕累!你這毒婦竟也來了陵刹?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,326評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤欢嘿,失蹤者是張志新(化名)和其女友劉穎衰琐,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體炼蹦,經(jīng)...
    沈念sama閱讀 45,782評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡羡宙,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,957評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了掐隐。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片狗热。...
    茶點(diǎn)故事閱讀 40,102評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖虑省,靈堂內(nèi)的尸體忽然破棺而出斗搞,到底是詐尸還是另有隱情,我是刑警寧澤慷妙,帶...
    沈念sama閱讀 35,790評(píng)論 5 346
  • 正文 年R本政府宣布僻焚,位于F島的核電站,受9級(jí)特大地震影響膝擂,放射性物質(zhì)發(fā)生泄漏虑啤。R本人自食惡果不足惜隙弛,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,442評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望狞山。 院中可真熱鬧全闷,春花似錦、人聲如沸萍启。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽勘纯。三九已至局服,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間驳遵,已是汗流浹背淫奔。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評(píng)論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留堤结,地道東北人唆迁。 一個(gè)月前我還...
    沈念sama閱讀 48,332評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像竞穷,于是被迫代替她去往敵國和親唐责。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,044評(píng)論 2 355

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