JVM中哪些地方會出現OOM


jvm中主要分為方法區、堆、棧、本地方法棧、程序計數器這幾部分,其中程序計數器是唯一不會出現OOM的

1. java堆溢出(heap)

Java堆內存主要用來存放運行過程中所有的對象,該區域OOM異常一般會有如下錯誤信息:

 java.lang.OutofMemoryError:Java heap space

 

可以通過dump的內存快照就能分析,到底是由於程序原因導致的內存泄露,還是由於沒有估計好JVM內存的大小而導致的內存溢出。

 

2. 棧溢出(stack)

棧用來存儲線程的局部變量表、操作數棧、動態鏈接、方法出口等信息。如果請求棧的深度不足時拋出的錯誤會包含類似下面的信息: java.lang.StackOverflowError。

 

由於每個線程占的內存大概為1M,因此線程的創建也需要內存空間。如果申請創建的線程比較多超過剩余內存的時候,也會拋出如下類似錯誤:java.lang.OutofMemoryError: unable to create new native thread

 

與棧相關的JVM參數有:

1、 -Xss: 每個線程的堆棧大小,JDK5.0以后每個線程堆棧大小為1M,以前每個線程堆棧大小為256K.

2、 在相同物理內存下,減小這個值能生成更多的線程.但是操作系統對1個進程內的線程數還是有限制的,不能無限生成。

 

出現棧溢出可能原因:

遞歸:遞歸里用到的局部變量存儲在堆棧中,堆棧的訪問效率高,速度快,但空間有限,遞歸太多變量需要一直入棧而不出棧,導致需要的內存空間大於堆棧的空間,棧空間是2M,堆空間內存空間。

 

運行時常量溢出(constant)

運行時常量保存在方法區,存放的主要是編譯器生成的各種字面量和符號引用,但是運行期間也可能將新的常量放入池中,比如String類的intern方法。如果該區域OOM,錯誤結果會包含類似下面的信息:

1 java.lang.OutofMemoryError: PermGen space

相關的JVM參數有:

1、 -XX:PermSize:設置持久代(perm gen)初始值,默認值為物理內存的1/64

2、 -XX:MaxPermSize:設置持久代最大值,默認為物理內存的1/4

 

方法區溢出

方法區主要存儲被虛擬機加載的類信息,如類名、訪問修飾符、常量池、字段描述、方法描述等。理論上在JVM啟動后該區域大小應該比較穩定,但是目前很多框架,比如Spring和Hibernate等在運行過程中都會動態生成類,因此也存在OOM的風險。如果該區域OOM,錯誤結果會包含類似下面的信息:

java.lang.OutofMemoryError: PermGen space

相關的JVM參數有:

1 -XX:PermSize:設置持久代(perm gen)初始值,默認值為物理內存的1/64

2 -XX:MaxPermSize:設置持久代最大值,默認為物理內存的1/4 

 


https://www.bilibili.com/read/cv9971526/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM