【Java面試題第三期】JVM中哪些地方會出現內存溢出?出現的緣由是什麼?

​    ​內存溢出(Out Of Memory)常常簡稱爲OOM,在jvm中主要分爲方法區、堆、棧、本地方法棧、程序計數器這幾部分,其中程序計數器是惟一不會出現OOM的,也就是說其餘區域都會出現OOM。下面來分別說明幾個區域出現OOM的狀況及特徵。java

 

1. java堆溢出(heap)面試

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

 java.lang.OutofMemoryError:Java heap space框架

 

能夠經過dump的內存快照就能分析,究竟是因爲程序緣由致使的內存泄露,仍是因爲沒有估計好JVM內存的大小而致使的內存溢出。jvm

 

2. 棧溢出(stack)spa

來存儲線程的局部變量表、操做數棧、動態連接、方法出口等信息。若是請求棧的深度不時拋出的錯誤會包含相似下面的信息: java.lang.StackOverflowError。操作系統

 

因爲每一個線程佔的內存大概爲1M,所以線程的建立也須要內存空間。若是申請建立的線程比較多超過剩餘內存的時候,也會拋出以下相似錯誤:java.lang.OutofMemoryError: unable to create new native thread線程

 

與棧相關的JVM參數有:對象

1 -Xss: 每一個線程的堆棧大小,JDK5.0之後每一個線程堆棧大小爲1M,之前每一個線程堆棧大小爲256K.blog

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 

 

更多Java面試題,可搜索小程序:IT面試題練習

相關文章
相關標籤/搜索