內存溢出(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面試題練習