JVM內(nèi)存區(qū)域介紹以及內(nèi)存溢出示例

在JVM的管控下鹉戚,Java程序員不再需要管理內(nèi)存的分配與釋放,這和在C和C++的世界是完全不一樣的咙冗。所以,在JVM的幫助下漂彤,Java程序員很少會關(guān)注內(nèi)存泄露和內(nèi)存溢出的問題雾消。但是,一旦JVM發(fā)生這些情況的時候挫望,如果你不清楚JVM內(nèi)存的內(nèi)存管理機制是很難定位與解決問題的立润。

JVM內(nèi)存區(qū)域介紹

首先需要弄明白JVM的內(nèi)存區(qū)域,JVM的內(nèi)存區(qū)域如圖:

來自《深入理解Java虛擬機》

下面分別對各個區(qū)域的功能做個說明:

程序計數(shù)器:是一塊較小的內(nèi)存空間媳板,可以看做是當前線程所執(zhí)行的字節(jié)碼的行號指示器桑腮。由于Java虛擬機的多線程是通過線程輪流切換并分配處理器執(zhí)行時間的方式來實現(xiàn)的,在任何一個確定的時刻蛉幸,一個核心破讨,或者一個處理器只會處理一個線程的某條指令。因此奕纫,線程切換后能恢復(fù)到正確的執(zhí)行位置提陶,每條線程都需要有一個獨立的程序計數(shù)器,各條線程之間計數(shù)器互不影響匹层,獨立存儲隙笆。所以這個地方也不會出現(xiàn)OutOfMemoryError情況的區(qū)域。

Java虛擬機棧:當每次調(diào)用一個方法的時候升筏,其實就是在JVM內(nèi)存上分配一個棧幀撑柔。這個棧幀包含一些局部變量表等信息。其中局部變量表所需的內(nèi)存空間在編譯期間就完成了分配您访。那針對這個區(qū)域規(guī)定了兩種異常信息:第一種乏冀,如果棧請求的深度大于虛擬機所允許的深度,將拋出StackOverflowError 異常洋只。第二種辆沦,如果虛擬機棧可以動態(tài)擴展识虚,如果擴展時無法申請到足夠的內(nèi)存肢扯,就會拋出OutOfMemoryError異常。

本地方法棧:主要為虛擬機使用到的native 方法服務(wù)担锤。這部分在JVM的規(guī)范里面沒有強制規(guī)定如何實現(xiàn)蔚晨。與虛擬機棧一樣,同樣會拋出StackOverflowError和OutOfMemoryError 兩種異常信息。

Java堆:是被所有線程共享的一塊內(nèi)存區(qū)域铭腕,該內(nèi)存區(qū)域的唯一目的就是存放對象實例银择,幾乎所有的對象實例都是在這里分配創(chuàng)建。由于他是虛擬機中管理的最大一塊內(nèi)存累舷,所以是主要的收集區(qū)域浩考。如果還需要再堆上分配實例,但是無法擴展出足夠的內(nèi)存空間被盈,將會拋出OutOfMemoryError異常析孽。

方法區(qū):也是各個線程共享的部分。主要用于存儲已被虛擬機加載的類信息只怎、常量袜瞬、靜態(tài)變量、即時編譯器編譯后的代碼等數(shù)據(jù)身堡。人們更愿意把這個部分稱為“永久代”邓尤。這個區(qū)域的內(nèi)存回收目標主要是針對常量池的回收和對類型的卸載,一般來說贴谎,這個區(qū)域的回收“成績”比較難以令人滿意汞扎。

內(nèi)存溢出的示例

通過分析內(nèi)存溢出,可以根據(jù)異常信息快速判斷是哪個區(qū)域的內(nèi)存溢出赴精,知道什么樣的代碼可能會導(dǎo)致這些區(qū)域內(nèi)存溢出,以及出現(xiàn)這些異常后該如何處理绞幌。(首先我們一般都是基于Sun公司的蕾哟,HotSpot虛擬機運行的。)

Java堆內(nèi)存溢出

如何產(chǎn)生Java堆內(nèi)存溢出:

只要在Java堆上不斷的創(chuàng)建對象莲蜘,并且保證GC Roots到對象之間存在可達的路徑來避免垃圾回收機制清楚這些對象谭确,那么在對象數(shù)量達到最大堆的容量限制后就會產(chǎn)生內(nèi)存溢出的異常。

Java堆內(nèi)存的大小設(shè)置是通過:-Xms -Xmx 兩個參數(shù)設(shè)置的票渠,-Xms是代表堆的初始化大小逐哈,-Xmx是代表堆的擴展大小。通過參數(shù)-XX: +HeapDumpOnOutOfMemoryError 可以讓虛擬機在出現(xiàn)內(nèi)存溢出異常時Dump出當前的內(nèi)存堆轉(zhuǎn)存儲快照以便事后進行分析问顷。

例如下面這段代碼就會Java堆內(nèi)存溢出:

堆空間內(nèi)存溢出實例代碼

這里運行時的命令是: java -Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError昂秃,限制堆的初始化大小和可擴展到的大小都是20M,并且當發(fā)生內(nèi)存溢出后將內(nèi)存堆快照保存為堆轉(zhuǎn)儲文件杜窄。

-Xms -Xmx 都是20M

當出現(xiàn)Java堆內(nèi)存溢出時肠骆,異常堆棧信息”java.lang.OutOfMemoryError”會跟著進一步提示”Java heap space”.要解決Java堆上的內(nèi)存溢出,需要通過工具進行詳細的排查塞耕,這里先不介紹蚀腿。

虛擬機棧和本地方法棧溢出

虛擬機棧的棧容量是通過-Xss 參數(shù)設(shè)定的。關(guān)于虛擬機棧會存在兩種異常:(但是一般都是拋出StackOverflowError.)

1. 如果線程請求的棧深度大于虛擬機所允許的最大深度扫外,將拋出StackOverflowError異常莉钙。

2. 如果虛擬機在擴展棧時無法申請到足夠的內(nèi)存空間廓脆,則拋出OutOfMemoryError異常。

下面這段代碼就會造成StackOverflowError異常:

棿庞瘢空間內(nèi)存溢出示例代碼


這里運行時的命令是:java -Xss160K TestStack停忿,限制棧的空間大小為160k。

出現(xiàn)的異常信息

方法區(qū)內(nèi)存溢出

常量池是屬于方法區(qū)的一部分蜀涨,為了驗證方法區(qū)內(nèi)存溢出瞎嬉,這里程序就不斷添加常量來造成方法區(qū)的內(nèi)存溢出。首先限制一下方法區(qū)的大泻窳: 我們可以通過-XX:PermSize 和 -XX:MaxPermSize限制方法區(qū)大小氧枣。

產(chǎn)生異常的示例代碼如下:

方法區(qū)內(nèi)存溢出示例代碼


這里運行時的命令是:java -XX:PermSize=2m -XX:MaxPermSize=2m ConstantPool

出現(xiàn)的異常信息

從運行結(jié)果中可以看到,運行時常量池溢出别垮,在OutOfMemoryError后面跟隨的提示信息是”PermGen space”便监。

總結(jié)

JVM內(nèi)存區(qū)域劃分,便于它能夠更加高效的管理自身的內(nèi)存碳想。當程序中出現(xiàn)這種由于JVM造成的內(nèi)存溢出的情況的時候烧董,需要根據(jù)不同的情況做不同的分析與處理。

JVM系列還會繼續(xù)往下寫胧奔,持續(xù)更新中逊移,不妨點個贊,*^_^*

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末龙填,一起剝皮案震驚了整個濱河市胳泉,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌岩遗,老刑警劉巖扇商,帶你破解...
    沈念sama閱讀 221,695評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異宿礁,居然都是意外死亡案铺,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評論 3 399
  • 文/潘曉璐 我一進店門梆靖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來控汉,“玉大人,你說我怎么就攤上這事返吻∠痉” “怎么了?”我有些...
    開封第一講書人閱讀 168,130評論 0 360
  • 文/不壞的土叔 我叫張陵思喊,是天一觀的道長壁酬。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么舆乔? 我笑而不...
    開封第一講書人閱讀 59,648評論 1 297
  • 正文 為了忘掉前任岳服,我火速辦了婚禮,結(jié)果婚禮上希俩,老公的妹妹穿的比我還像新娘吊宋。我一直安慰自己,他們只是感情好颜武,可當我...
    茶點故事閱讀 68,655評論 6 397
  • 文/花漫 我一把揭開白布璃搜。 她就那樣靜靜地躺著,像睡著了一般鳞上。 火紅的嫁衣襯著肌膚如雪这吻。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,268評論 1 309
  • 那天篙议,我揣著相機與錄音唾糯,去河邊找鬼。 笑死鬼贱,一個胖子當著我的面吹牛移怯,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播这难,決...
    沈念sama閱讀 40,835評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼舟误,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了姻乓?” 一聲冷哼從身側(cè)響起嵌溢,我...
    開封第一講書人閱讀 39,740評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎糖权,沒想到半個月后堵腹,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體炸站,經(jīng)...
    沈念sama閱讀 46,286評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡星澳,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,375評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了旱易。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片禁偎。...
    茶點故事閱讀 40,505評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖阀坏,靈堂內(nèi)的尸體忽然破棺而出如暖,到底是詐尸還是另有隱情,我是刑警寧澤忌堂,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布盒至,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏枷遂。R本人自食惡果不足惜樱衷,卻給世界環(huán)境...
    茶點故事閱讀 41,873評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望酒唉。 院中可真熱鬧矩桂,春花似錦、人聲如沸痪伦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,357評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽网沾。三九已至癞蚕,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間绅这,已是汗流浹背涣达。 一陣腳步聲響...
    開封第一講書人閱讀 33,466評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留证薇,地道東北人度苔。 一個月前我還...
    沈念sama閱讀 48,921評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像浑度,于是被迫代替她去往敵國和親寇窑。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,515評論 2 359

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