JavaSE知識(shí)點(diǎn)18java深入了解JVM內(nèi)存管理

1 JVM內(nèi)存分配

  • 1 在討論JVM內(nèi)存管理之前,先來看一下Java程序具體執(zhí)行的過程:


  • 2 如上圖所示,首先Java源代碼文件(.java后綴)會(huì)被Java編譯器編譯為字節(jié)碼文件(.class后綴),然后由JVM中的類加載器加載字節(jié)碼文件,加載完畢之后浩嫌,交由JVM執(zhí)行引擎執(zhí)行。
  • 3 在整個(gè)程序執(zhí)行過程中补胚,JVM會(huì)用一段空間來存儲(chǔ)程序執(zhí)行期間需要用到的數(shù)據(jù)和相關(guān)信息码耐,這段空間一般被稱作為Runtime Data Area(運(yùn)行時(shí)數(shù)據(jù)區(qū)),也就是我們常說的JVM內(nèi)存溶其。因此骚腥,在Java中我們常常說到的內(nèi)存管理就是針對(duì)這段空間進(jìn)行管理,這里主要說內(nèi)存分配瓶逃。

2 運(yùn)行時(shí)數(shù)據(jù)區(qū)包括哪幾部分束铭?

  • 1 運(yùn)行時(shí)數(shù)據(jù)區(qū)通常包括這幾個(gè)部分:程序計(jì)數(shù)器(Program Counter Register)、Java棧(VM Stack)厢绝、本地方法棧(Native Method Stack)契沫、方法區(qū)(Method Area)、堆(Heap)昔汉。


  • 2 如上圖所示懈万,JVM中的運(yùn)行時(shí)數(shù)據(jù)區(qū)應(yīng)該包括這些部分。在JVM規(guī)范中雖然規(guī)定了程序在執(zhí)行期間運(yùn)行時(shí)數(shù)據(jù)區(qū)應(yīng)該包括這幾部分靶病,但是至于具體如何實(shí)現(xiàn)并沒有做出規(guī)定会通,不同的虛擬機(jī)廠商可以有不同的實(shí)現(xiàn)方式。

3 運(yùn)行時(shí)數(shù)據(jù)區(qū)的每部分到底存儲(chǔ)了哪些數(shù)據(jù)娄周?

  • 1 程序計(jì)數(shù)器
    程序計(jì)數(shù)器(Program Counter Register)涕侈,也有稱作為PC寄存器。由于在JVM中煤辨,多線程是通過線程輪流切換來獲得CPU執(zhí)行時(shí)間的裳涛,因此,在任一具體時(shí)刻掷酗,一個(gè)CPU的內(nèi)核只會(huì)執(zhí)行一條線程中的指令调违,因此,為了能夠使得每個(gè)線程都在線程切換后能夠恢復(fù)在切換之前的程序執(zhí)行位置泻轰,每個(gè)線程都需要有自己獨(dú)立的程序計(jì)數(shù)器技肩,并且不能互相被干擾,否則就會(huì)影響到程序的正常執(zhí)行次序。因此虚婿,可以這么說旋奢,程序計(jì)數(shù)器是每個(gè)線程所私有的。
  • 2 Java棧
    Java棧也稱作虛擬機(jī)棧然痊,Java棧是Java方法執(zhí)行的內(nèi)存模型至朗。為什么這么說呢?下面就來解釋一下其中的原因剧浸。
    1)Java棧中存放的是一個(gè)個(gè)的棧幀锹引,每個(gè)棧幀對(duì)應(yīng)一個(gè)被調(diào)用的方法,在棧幀中包括局部變量表(Local Variables)唆香、操作數(shù)棧(Operand Stack)嫌变、指向當(dāng)前方法所屬的類的運(yùn)行時(shí)常量池的引用(Reference to runtime constant pool)、方法返回地址(Return Address)和一些額外的附加信息躬它。
    2)當(dāng)線程執(zhí)行一個(gè)方法時(shí)腾啥,就會(huì)隨之創(chuàng)建一個(gè)對(duì)應(yīng)的棧幀,并將建立的棧幀壓棧冯吓。當(dāng)方法執(zhí)行完畢之后倘待,便會(huì)將棧幀出棧。因此可知组贺,線程當(dāng)前執(zhí)行的方法所對(duì)應(yīng)的棧幀必定位于Java棧的頂部凸舵。
    3)講到這里,大家就應(yīng)該會(huì)明白為什么 在 使用 遞歸方法的時(shí)候容易導(dǎo)致棧內(nèi)存溢出的現(xiàn)象了以及為什么棧區(qū)的空間不用程序員去管理了(當(dāng)然在Java中锣披,程序員基本不用關(guān)系到內(nèi)存分配和釋放的事情贞间,因?yàn)镴ava有自己的垃圾回收機(jī)制)贿条,這部分空間的分配和釋放都是由系統(tǒng)自動(dòng)實(shí)施的雹仿。對(duì)于所有的程序設(shè)計(jì)語言來說,棧這部分空間對(duì)程序員來說是不透明的整以。
    4)局部變量表胧辽,顧名思義,想必不用解釋大家應(yīng)該明白它的作用了吧公黑。就是用來存儲(chǔ)方法中的局部變量(包括在方法中聲明的非靜態(tài)變量以及函數(shù)形參)邑商。對(duì)于基本數(shù)據(jù)類型的變量,則直接存儲(chǔ)它的值凡蚜,對(duì)于引用類型的變量人断,則存的是指向?qū)ο蟮囊谩>植孔兞勘淼拇笮≡诰幾g器就可以確定其大小了朝蜘,因此在程序執(zhí)行期間局部變量表的大小是不會(huì)改變的恶迈。
    5)操作數(shù)棧,棧最典型的一個(gè)應(yīng)用就是用來對(duì)表達(dá)式求值谱醇。想想一個(gè)線程執(zhí)行方法的過程中暇仲,實(shí)際上就是不斷執(zhí)行語句的過程步做,而歸根到底就是進(jìn)行計(jì)算的過程。因此可以這么說奈附,程序中的所有計(jì)算過程都是在借助于操作數(shù)棧來完成的全度。
    6)指向運(yùn)行時(shí)常量池的引用,因?yàn)樵诜椒▓?zhí)行的過程中有可能需要用到類中的常量斥滤,所以必須要有一個(gè)引用指向運(yùn)行時(shí)常量将鸵。
    7)方法返回地址,當(dāng)一個(gè)方法執(zhí)行完畢之后佑颇,要返回之前調(diào)用它的地方咨堤,因此在棧幀中必須保存一個(gè)方法返回地址。
    8)由于每個(gè)線程正在執(zhí)行的方法可能不同漩符,因此每個(gè)線程都會(huì)有一個(gè)自己的Java棧一喘,互不干擾。
  • 3 本地方法棧
    本地方法棧與Java棧的作用和原理非常相似嗜暴。區(qū)別只不過是Java棧是為執(zhí)行Java方法服務(wù)的凸克,而本地方法棧則是為執(zhí)行本地方法(Native Method)服務(wù)的。在JVM規(guī)范中闷沥,并沒有對(duì)本地方法棧的具體實(shí)現(xiàn)方法以及數(shù)據(jù)結(jié)構(gòu)作強(qiáng)制規(guī)定萎战,虛擬機(jī)可以自由實(shí)現(xiàn)它。在HotSopt虛擬機(jī)中直接就把本地方法棧和Java棧合二為一舆逃。
  • 4 堆
    1)在C語言中蚂维,堆這部分空間是唯一一個(gè)程序員可以管理的內(nèi)存區(qū)域。程序員可以通過malloc函數(shù)和free函數(shù)在堆上申請(qǐng)和釋放空間路狮。那么在Java中是怎么樣的呢虫啥?
    2)Java中的堆是用來存儲(chǔ)對(duì)象本身的以及數(shù)組(當(dāng)然,數(shù)組引用是存放在Java棧中的)奄妨。只不過和C語言中的不同涂籽,在Java中,程序員基本不用去關(guān)心空間釋放的問題砸抛,Java的垃圾回收機(jī)制會(huì)自動(dòng)進(jìn)行處理评雌。因此這部分空間也是Java垃圾收集器管理的主要區(qū)域。另外直焙,堆是被所有線程共享的景东,在JVM中只有一個(gè)堆
  • 5.方法區(qū)
    1)方法區(qū)在JVM中也是一個(gè)非常重要的區(qū)域奔誓,它與堆一樣斤吐,是被線程共享的區(qū)域。在方法區(qū)中,存儲(chǔ)了每個(gè)類的信息(包括類的名稱曲初、方法信息体谒、字段信息)、靜態(tài)變量臼婆、常量以及編譯器編譯后的代碼等抒痒。
    2)在Class文件中除了類的字段、方法颁褂、接口等描述信息外故响,還有一項(xiàng)信息是常量池,用來存儲(chǔ)編譯期間生成的字面量和符號(hào)引用颁独。
    3)在方法區(qū)中有一個(gè)非常重要的部分就是運(yùn)行時(shí)常量池彩届,它是每一個(gè)類或接口的常量池的運(yùn)行時(shí)表示形式,在類和接口被加載到JVM后誓酒,對(duì)應(yīng)的運(yùn)行時(shí)常量池就被創(chuàng)建出來樟蠕。當(dāng)然并非Class文件常量池中的內(nèi)容才能進(jìn)入運(yùn)行時(shí)常量池,在運(yùn)行期間也可將新的常量放入運(yùn)行時(shí)常量池中靠柑,比如String的intern方法寨辩。當(dāng)應(yīng)用會(huì)加載很多Class的話,就很可能出現(xiàn)PermGen space錯(cuò)誤。
    4)Java中的堆是 JVM 所管理的最大的一塊內(nèi)存空間歼冰,主要用于存放各種類的實(shí)例對(duì)象靡狞。 下面單獨(dú)講講Java堆

4 Java堆內(nèi)存的分配和回收

  • 1 新生代:Young Generation,主要用來存放新生的對(duì)象隔嫡。
  • 2 老年代:Old Generation或者稱作Tenured Generation甸怕,主要存放應(yīng)用程序聲明周期長的內(nèi)存對(duì)象。


  • 3 堆大小 = 新生代 + 老年代腮恩。其中梢杭,堆的大小可以通過參數(shù) –Xms、-Xmx 來指定庆揪。
  • 4 默認(rèn)的式曲,新生代 ( Young ) 與老年代 ( Old ) 的比例的值為 1:2 ( 該值可以通過參數(shù) –XX:NewRatio 來指定 )妨托,即:新生代 ( Young ) = 1/3 的堆空間大小缸榛。老年代 ( Old ) = 2/3 的堆空間大小。其中兰伤,新生代 ( Young ) 被細(xì)分為 Eden 和 兩個(gè) Survivor 區(qū)域内颗,這兩個(gè) Survivor 區(qū)域分別被命名為 from 和 to,以示區(qū)分敦腔。
  • 5 默認(rèn)的均澳,Eden : from : to = 8 : 1 : 1 ( 可以通過參數(shù) –XX:SurvivorRatio 來設(shè)定 ),即: Eden = 8/10 的新生代空間大小,from = to = 1/10 的新生代空間大小找前。
  • 6 JVM 每次只會(huì)使用 Eden 和其中的一塊 Survivor 區(qū)域來為對(duì)象服務(wù)糟袁,所以無論什么時(shí)候,總是有一塊 Survivor 區(qū)域是空閑著的躺盛。因此项戴,新生代實(shí)際可用的內(nèi)存空間為 9/10 ( 即90% )的新生代空間。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末槽惫,一起剝皮案震驚了整個(gè)濱河市周叮,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌界斜,老刑警劉巖仿耽,帶你破解...
    沈念sama閱讀 219,427評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異各薇,居然都是意外死亡项贺,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門峭判,熙熙樓的掌柜王于貴愁眉苦臉地迎上來敬扛,“玉大人,你說我怎么就攤上這事朝抖∩都” “怎么了?”我有些...
    開封第一講書人閱讀 165,747評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵治宣,是天一觀的道長急侥。 經(jīng)常有香客問我,道長侮邀,這世上最難降的妖魔是什么坏怪? 我笑而不...
    開封第一講書人閱讀 58,939評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮绊茧,結(jié)果婚禮上铝宵,老公的妹妹穿的比我還像新娘。我一直安慰自己华畏,他們只是感情好鹏秋,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著亡笑,像睡著了一般侣夷。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上仑乌,一...
    開封第一講書人閱讀 51,737評(píng)論 1 305
  • 那天百拓,我揣著相機(jī)與錄音琴锭,去河邊找鬼。 笑死衙传,一個(gè)胖子當(dāng)著我的面吹牛决帖,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蓖捶,決...
    沈念sama閱讀 40,448評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼古瓤,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了腺阳?” 一聲冷哼從身側(cè)響起落君,我...
    開封第一講書人閱讀 39,352評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎亭引,沒想到半個(gè)月后绎速,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,834評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡焙蚓,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評(píng)論 3 338
  • 正文 我和宋清朗相戀三年纹冤,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片购公。...
    茶點(diǎn)故事閱讀 40,133評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡萌京,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出宏浩,到底是詐尸還是另有隱情知残,我是刑警寧澤,帶...
    沈念sama閱讀 35,815評(píng)論 5 346
  • 正文 年R本政府宣布比庄,位于F島的核電站求妹,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏佳窑。R本人自食惡果不足惜制恍,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望神凑。 院中可真熱鬧净神,春花似錦、人聲如沸溉委。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽薛躬。三九已至俯渤,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間型宝,已是汗流浹背八匠。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評(píng)論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留趴酣,地道東北人梨树。 一個(gè)月前我還...
    沈念sama閱讀 48,398評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像岖寞,于是被迫代替她去往敵國和親抡四。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評(píng)論 2 355

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