異常、堆內(nèi)存溢出、OOM的幾種情況

版權(quán)聲明:本文為博主原創(chuàng)文章,未經(jīng)博主允許不得轉(zhuǎn)載。

目錄(?)[+]

1堆內(nèi)存溢出

2Java異常

OOM

1、堆內(nèi)存溢出

【情況一】:

Java.lang.OutOfMemoryError:Javaheap space:這種是java堆內(nèi)存不夠,一個(gè)原因是真不夠,另一個(gè)原因是程序中有死循環(huán);

如果是java堆內(nèi)存不夠的話,可以通過調(diào)整JVM下面的配置來解決:

< jvm-arg>-Xms3062m < / jvm-arg>

< jvm-arg>-Xmx3062m < / jvm-arg>

【情況二】

java.lang.OutOfMemoryError: GC overhead limit exceeded

【解釋】:JDK6新增錯(cuò)誤類型,當(dāng)GC為釋放很小空間占用大量時(shí)間時(shí)拋出;一般是因?yàn)槎烟。瑢?dǎo)致異常的原因,沒有足夠的內(nèi)存。

【解決方案】:

1、查看系統(tǒng)是否有使用大內(nèi)存的代碼或死循環(huán);

2、通過添加JVM配置,來限制使用內(nèi)存:

< jvm-arg>-XX:-UseGCOverheadLimit< /jvm-arg>

【情況三】:

java.lang.OutOfMemoryError: PermGen space:這種是P區(qū)內(nèi)存不夠,可通過調(diào)整JVM的配置:

< jvm-arg>-XX:MaxPermSize=128m< /jvm-arg>

< jvm-arg>-XXermSize=128m< /jvm-arg>

【注】:

JVM的Perm區(qū)主要用于存放Class和Meta信息的,Class在被Loader時(shí)就會(huì)被放到PermGen space,這個(gè)區(qū)域成為年老代,GC在主程序運(yùn)行期間不會(huì)對(duì)年老區(qū)進(jìn)行清理,默認(rèn)是64M大小,當(dāng)程序需要加載的對(duì)象比較多時(shí),超過64M就會(huì)報(bào)這部分內(nèi)存溢出了,需要加大內(nèi)存分配,一般128m足夠。

【情況四】:

java.lang.OutOfMemoryError: Direct buffer memory

調(diào)整-XX:MaxDirectMemorySize= 參數(shù),如添加JVM配置:

< jvm-arg>-XX:MaxDirectMemorySize=128m< /jvm-arg>

【情況五】:

java.lang.OutOfMemoryError: unable to create new native thread

【原因】:Stack空間不足以創(chuàng)建額外的線程,要么是創(chuàng)建的線程過多,要么是Stack空間確實(shí)小了。

【解決】:由于JVM沒有提供參數(shù)設(shè)置總的stack空間大小,但可以設(shè)置單個(gè)線程棧的大小;而系統(tǒng)的用戶空間一共是3G,除了Text/Data/BSS /MemoryMapping幾個(gè)段之外,Heap和Stack空間的總量有限,是此消彼長(zhǎng)的。因此遇到這個(gè)錯(cuò)誤,可以通過兩個(gè)途徑解決:

1.通過 -Xss啟動(dòng)參數(shù)減少單個(gè)線程棧大小,這樣便能開更多線程(當(dāng)然不能太小,太小會(huì)出現(xiàn)StackOverflowError);

2.通過-Xms -Xmx 兩參數(shù)減少Heap大小,將內(nèi)存讓給Stack(前提是保證Heap空間夠用)。

【情況六】:

java.lang.StackOverflowError

【原因】:這也內(nèi)存溢出錯(cuò)誤的一種,即線程棧的溢出,要么是方法調(diào)用層次過多(比如存在無限遞歸調(diào)用),要么是線程棧太小。

【解決】:優(yōu)化程序設(shè)計(jì),減少方法調(diào)用層次;調(diào)整-Xss參數(shù)增加線程棧大小。

2、Java異常

Throwable

Throwable是 Java 語言中所有錯(cuò)誤或異常的超類。

Throwable包含兩個(gè)子類: Error 和 Exception 。它們通常用于指示發(fā)生了異常情況。

Throwable包含了其線程創(chuàng)建時(shí)線程執(zhí)行堆棧的快照,它提供了printStackTrace()等接口用于獲取堆棧跟蹤數(shù)據(jù)等信息。

Exception

Exception及其子類是 Throwable 的一種形式,它指出了合理的應(yīng)用程序想要捕獲的條件。

RuntimeException

RuntimeException是那些可能在 Java 虛擬機(jī)正常運(yùn)行期間拋出的異常的超類。

編譯器不會(huì)檢查RuntimeException異常例如,除數(shù)為零時(shí),拋出ArithmeticException異常。RuntimeException是ArithmeticException的超類。當(dāng)代碼發(fā)生除數(shù)為零的情況時(shí),倘若既”沒有通過throws聲明拋出ArithmeticException異常”,也”沒有通過try…catch…處理該異常”,也能通過編譯。這就是我們所說的”編譯器不會(huì)檢查RuntimeException異常”!

如果代碼會(huì)產(chǎn)生RuntimeException異常,則需要通過修改代碼進(jìn)行避免。 例如,若會(huì)發(fā)生除數(shù)為零的情況,則需要通過代碼避免該情況的發(fā)生!

Error

和Exception一樣, Error也是Throwable的子類。 它用于指示合理的應(yīng)用程序不應(yīng)該試圖捕獲的嚴(yán)重問題,大多數(shù)這樣的錯(cuò)誤都是異常條件。

和RuntimeException一樣,編譯器也不會(huì)檢查Error

Java將可拋出(Throwable)的結(jié)構(gòu)分為三種類型:被檢查的異常(Checked Exception),運(yùn)行時(shí)異常(RuntimeException)和錯(cuò)誤(Error)

(01) 運(yùn)行時(shí)異常

定義 : RuntimeException及其子類都被稱為運(yùn)行時(shí)異常。

特點(diǎn) :Java編譯器不會(huì)檢查它。 也就是說,當(dāng)程序中可能出現(xiàn)這類異常時(shí),倘若既”沒有通過throws聲明拋出它”,也”沒有用try-catch語句捕獲它”,還是會(huì)編譯通過。例如,除數(shù)為零時(shí)產(chǎn)生的ArithmeticException異常數(shù)組越界時(shí)產(chǎn)生的IndexOutOfBoundsException異常,fail-fail機(jī)制產(chǎn)生的ConcurrentModificationException異常等,都屬于運(yùn)行時(shí)異常。

雖然Java編譯器不會(huì)檢查運(yùn)行時(shí)異常,但是我們也可以通過throws進(jìn)行聲明拋出,也可以通過try-catch對(duì)它進(jìn)行捕獲處理。

如果產(chǎn)生運(yùn)行時(shí)異常,則需要通過修改代碼來進(jìn)行避免。 例如,若會(huì)發(fā)生除數(shù)為零的情況,則需要通過代碼避免該情況的發(fā)生!

(02) 被檢查的異常

定義 :? Exception類本身,以及Exception的子類中除了”運(yùn)行時(shí)異常”之外的其它子類都屬于被檢查異常。

特點(diǎn) :Java編譯器會(huì)檢查它此類異常,要么通過throws進(jìn)行聲明拋出,要么通過try-catch進(jìn)行捕獲處理,否則不能通過編譯。例如,CloneNotSupportedException就屬于被檢查異常。當(dāng)通過clone()接口去克隆一個(gè)對(duì)象,而該對(duì)象對(duì)應(yīng)的類沒有實(shí)現(xiàn)Cloneable接口,就會(huì)拋出CloneNotSupportedException異常。

被檢查異常通常都是可以恢復(fù)的。

(03) 錯(cuò)誤

定義 : Error類及其子類。

特點(diǎn) : 和運(yùn)行時(shí)異常一樣,編譯器也不會(huì)對(duì)錯(cuò)誤進(jìn)行檢查

當(dāng)資源不足、約束失敗、或是其它程序無法繼續(xù)運(yùn)行的條件發(fā)生時(shí),就產(chǎn)生錯(cuò)誤。程序本身無法修復(fù)這些錯(cuò)誤的。例如,VirtualMachineError就屬于錯(cuò)誤。

按照J(rèn)ava慣例,我們是不應(yīng)該是實(shí)現(xiàn)任何新的Error子類的!

對(duì)于上面的3種結(jié)構(gòu),我們?cè)趻伋霎惓;蝈e(cuò)誤時(shí),到底該哪一種?《Effective Java》中給出的建議是:對(duì)于可以恢復(fù)的條件使用被檢查異常,對(duì)于程序錯(cuò)誤使用運(yùn)行時(shí)異常。

OOM

1,? OutOfMemoryError異常

除了程序計(jì)數(shù)器外,虛擬機(jī)內(nèi)存的其他幾個(gè)運(yùn)行時(shí)區(qū)域都有發(fā)生OutOfMemoryError(OOM)異常的可能,

javaHeap 溢出

一般的異常信息:java.lang.OutOfMemoryError:Java heap spacess

java堆用于存儲(chǔ)對(duì)象實(shí)例,我們只要不斷的創(chuàng)建對(duì)象,并且保證GC Roots到對(duì)象之間有可達(dá)路徑來避免垃圾回收機(jī)制清除這些對(duì)象,就會(huì)在對(duì)象數(shù)量達(dá)到最大堆容量限制后產(chǎn)生內(nèi)存溢出異常。

出現(xiàn)這種異常,一般手段是先通過內(nèi)存映像分析工具(如Eclipse Memory

Analyzer)對(duì)dump出來的堆轉(zhuǎn)存快照進(jìn)行分析,重點(diǎn)是確認(rèn)內(nèi)存中的對(duì)象是否是必要的,先分清是因?yàn)閮?nèi)存泄漏(Memory

Leak)還是內(nèi)存溢出(Memory Overflow)。

如果是內(nèi)存泄漏,可進(jìn)一步通過工具查看泄漏對(duì)象到GC Roots的引用鏈。于是就能找到泄漏對(duì)象時(shí)通過怎樣的路徑與GC Roots相關(guān)聯(lián)并導(dǎo)致垃圾收集器無法自動(dòng)回收。

如果不存在泄漏,那就應(yīng)該檢查虛擬機(jī)的參數(shù)(-Xmx與-Xms)的設(shè)置是否適當(dāng)。

2,? 虛擬機(jī)棧和本地方法棧溢出

如果線程請(qǐng)求的棧深度大于虛擬機(jī)所允許的最大深度,將拋出StackOverflowError異常。

如果虛擬機(jī)在擴(kuò)展棧時(shí)無法申請(qǐng)到足夠的內(nèi)存空間,則拋出OutOfMemoryError異常

這里需要注意當(dāng)棧的大小越大可分配的線程數(shù)就越少

3,? 運(yùn)行時(shí)常量池溢出

異常信息:java.lang.OutOfMemoryError:PermGen space

如果要向運(yùn)行時(shí)常量池中添加內(nèi)容,最簡(jiǎn)單的做法就是使用String.intern()這個(gè)Native方法。該方法的作用是:如果池中已經(jīng)包含一個(gè)等于此String的字符串,則返回代表池中這個(gè)字符串的String對(duì)象;否則,將此String對(duì)象包含的字符串添加到常量池中,并且返回此String對(duì)象的引用。由于常量池分配在方法區(qū)內(nèi),我們可以通過-XX:PermSize和-XX:MaxPermSize限制方法區(qū)的大小,從而間接限制其中常量池的容量。

4,? 方法區(qū)溢出

方法區(qū)用于存放Class的相關(guān)信息,如類名、訪問修飾符、常量池、字段描述、方法描述等。

異常信息:java.lang.OutOfMemoryError:PermGen space

方法區(qū)溢出也是一種常見的內(nèi)存溢出異常,一個(gè)類如果要被垃圾收集器回收,判定條件是很苛刻的。在經(jīng)常動(dòng)態(tài)生成大量Class的應(yīng)用中,要特別注意這點(diǎn)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,732評(píng)論 6 539
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,214評(píng)論 3 426
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,781評(píng)論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,588評(píng)論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,315評(píng)論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,699評(píng)論 1 327
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,698評(píng)論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,882評(píng)論 0 289
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,441評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,189評(píng)論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,388評(píng)論 1 372
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,933評(píng)論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,613評(píng)論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,023評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,310評(píng)論 1 293
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,112評(píng)論 3 398
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,334評(píng)論 2 377

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

  • JVM內(nèi)存模型Java虛擬機(jī)(Java Virtual Machine=JVM)的內(nèi)存空間分為五個(gè)部分,分別是: ...
    光劍書架上的書閱讀 2,550評(píng)論 2 26
  • Java8張圖 11、字符串不變性 12、equals()方法、hashCode()方法的區(qū)別 13、...
    Miley_MOJIE閱讀 3,722評(píng)論 0 11
  • 嘎吱嘎吱的咬嚼聲,在晚上夜深人靜時(shí)特別明顯。自從家里二樓裝空調(diào)在外墻打了個(gè)洞,后來因?yàn)槲恢貌粚?duì)棄置,又因偷懶沒有及...
    遐想的天空閱讀 647評(píng)論 0 0
  • 三年前,他和她是無話不談的朋友。談?wù)巍矍椤W(xué)習(xí),他們什么都能談,能夠談到深更半夜都沒有關(guān)系。 然后,忽然有一天...
    laviedX閱讀 177評(píng)論 0 0
  • 其實(shí)我也不知道應(yīng)該如何形容這幅畫,本來想畫一層的,結(jié)果畫面結(jié)構(gòu)不好,又加了一層,畫樹的時(shí)候情不自禁的只畫了半邊,然...
    GraceAn閱讀 371評(píng)論 0 0