troubleshoot之:分析OutOfMemoryError异常
文章目錄
- 簡介
- OutOfMemoryError
- java.lang.OutOfMemoryError: Java heap space
- java.lang.OutOfMemoryError: GC Overhead limit exceeded
- java.lang.OutOfMemoryError: Requested array size exceeds VM limit
- java.lang.OutOfMemoryError: Metaspace
- java.lang.OutOfMemoryError: request size bytes for reason. Out of swap space?
- java.lang.OutOfMemoryError: Compressed class space
- OutOfMemoryError: reason stack_trace_with_native_method
- 總結(jié)
簡介
java.lang.OutOfMemoryError應(yīng)該java應(yīng)用程序中非常常見的一個(gè)的錯(cuò)誤了。
那么OutOfMemoryError產(chǎn)生的原因是什么呢?我們怎么去查找相應(yīng)的錯(cuò)誤呢?一起來看看吧。
OutOfMemoryError
先看一下OutOfMemoryError的定義,OutOfMemoryError繼承自
VirtualMachineError,它是Error的一種,表示的是應(yīng)用程序無法處理的異常,一般情況下會(huì)導(dǎo)致虛擬機(jī)退出。
一般情形下,如果heap沒有更多的空間來分配對象,就會(huì)拋出OutOfMemoryError。
還有一種情況是沒有足夠的native memory來加載java class。
在極少數(shù)情況下,如果花費(fèi)大量時(shí)間進(jìn)行垃圾回收并且只釋放了很少的內(nèi)存,也有可能引發(fā)java.lang.OutOfMemoryError。
如果發(fā)生OutOfMemoryError,同時(shí)會(huì)輸出相應(yīng)的stack trace信息。
下面我們分析一下各個(gè)不同的OutOfMemoryError。
java.lang.OutOfMemoryError: Java heap space
Java heap space表示的是新對象不能在java heap中分配。
如果遇到這種問題,第一個(gè)要想到的解決方法就是去看配置的heap大小是不是太小了。
當(dāng)然,如果是一個(gè)一直都在運(yùn)行的程序,突然間發(fā)生這種問題就要警惕了。因?yàn)橛锌赡軙?huì)存在潛在的內(nèi)存泄露。需要進(jìn)一步分析。
還有一種情況,如果java對象實(shí)現(xiàn)了finalize方法,那么該對象在垃圾回收的時(shí)候并不會(huì)立刻被回收。而是放到一個(gè)finalization隊(duì)列中。
這個(gè)隊(duì)列會(huì)由終結(jié)器守護(hù)線程來執(zhí)行。如果終結(jié)器守護(hù)線程的執(zhí)行速度比對象放入終結(jié)器隊(duì)列中的速度要慢的話,就會(huì)導(dǎo)致java對象不能被及時(shí)回收。
如果應(yīng)用程序創(chuàng)建了高優(yōu)先級(jí)的線程,那么高優(yōu)先級(jí)的線程將有可能會(huì)導(dǎo)致對象被放入finalization隊(duì)列的速度比終結(jié)器守護(hù)線程的處理速度慢。
java.lang.OutOfMemoryError: GC Overhead limit exceeded
GC overhead limit exceeded表示的是GC一直都在運(yùn)行,從而導(dǎo)致java程序本身執(zhí)行非常慢。
如果一個(gè)java程序98%的時(shí)間都在做GC操作,但是只恢復(fù)了2%的heap空間,并且持續(xù)5次。那么java.lang.OutOfMemoryError將會(huì)被拋出。
可以使用下面的參數(shù)來關(guān)閉這個(gè)功能。
-XX:-UseGCOverheadLimitjava.lang.OutOfMemoryError: Requested array size exceeds VM limit
這個(gè)錯(cuò)誤的意思是,要分配的array比heap size大。
比如說設(shè)置的最大heap大小是256M,但是分配了一個(gè)300M的數(shù)組,就會(huì)出現(xiàn)這個(gè)問題。
java.lang.OutOfMemoryError: Metaspace
從JDK8之后,Metaspace已經(jīng)移到了java的本地內(nèi)存空間中。如果Metaspace超出了限制的大小,那么java.lang.OutOfMemoryError也會(huì)拋出。
Metaspace的空間大小可以通過MaxMetaSpaceSize來設(shè)置。
java.lang.OutOfMemoryError: request size bytes for reason. Out of swap space?
當(dāng)本地堆分配失敗并且本地堆即將耗盡的時(shí)候就會(huì)報(bào)這個(gè)異常。
java.lang.OutOfMemoryError: Compressed class space
在64位的平臺(tái),對象指針可以用32位表示(對象指針壓縮)。
對象指針壓縮可以通過:
UseCompressedClassPointers來啟用,默認(rèn)這個(gè)參數(shù)是開啟的。
我們可以使用CompressedClassSpaceSize來設(shè)置指針壓縮空間的大小。
注意,只有klass元信息是存放在CompressedClassSpaceSize設(shè)置的空間中的,而其他的元信息都是存放在Metaspace中的。
OutOfMemoryError: reason stack_trace_with_native_method
這個(gè)錯(cuò)誤表示本地方法遇到分配失敗。
遇到這種問題可能需要操作系統(tǒng)的本地調(diào)試工具來解決。
總結(jié)
本文介紹了OutOfMemoryError的不同種類,希望大家能夠有所收獲。
本文作者:flydean程序那些事
本文鏈接:http://www.flydean.com/jvm-outofmemoryerror-analysis/
本文來源:flydean的博客
歡迎關(guān)注我的公眾號(hào):程序那些事,更多精彩等著您!
總結(jié)
以上是生活随笔為你收集整理的troubleshoot之:分析OutOfMemoryError异常的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 看动画学算法之:二叉搜索树BST
- 下一篇: troubleshoot之:使用JFR分