1:棧溢出java
這個簡單理解就是方法運行期間須要分配內存,這類的內存就稱之爲棧。這類的溢出通常發生在方法的棧太長了,超出了最大深度,或者是超出了內存的。就會爆棧溢出。java 的異常對象爲 StackOverFlowError。異步
上代碼:如何模擬棧溢出來理解這個,簡單的及時寫一個不會跳出的遞歸。code
//若是不當心進入了這樣的一個方法,毫無疑問他就會爆出 棧溢出,這個方法棧愈來愈長,會逐漸從虛擬機中分配新的內存。也不退出 //就會有棧溢出。 public void static enter(int number){ number++; enter(number) }
這是一個極端的例子,來簡單的描述棧溢出發生的一個場景,現實中估計沒人會在生產環境中寫出這麼一個代碼出來,就是一個思路。若是發生了 stackoverflowError的話,能夠順着這個思路去分析問題。對象
2:堆泄露遞歸
堆簡單說就是你生成出來的一系列的對象,何時會發生堆泄露呢,若是這堆對象一直存在,而且不能被垃圾回收,多到虛擬機沒法爲對象分配新的內存空間的時候,他就要爆堆泄露了。內存
public class HeapOMM{ public HeapOMM{ } public static void main(String args[]){ // 無止境的new 對象出來,而且也得不到回收,當內存再也不有空間尅使用的時候,虛擬機就要爆OMM了 while(true){ List<HeapOMM> list = new ArrayList<HeapOMM>(); list.add(new HeapOMM); } } }
也是一個思路。用於定位OMM發生的根本緣由。字符串
3:方法區和運行常量池的溢出虛擬機
這種狀況不多,實在看書的時候發現的一種,在工做中尚未遇到過方法區的溢出。String的intern()方法,在字符串常量池中若是已經包含了一個String對象,則會直接返回池中的對象,若是沒有的話,則會new一個放到常亮池中,若是一直new 不一樣的String對象出來,常量池就會一直增長,當不知足虛擬機內存分配的時候也會爆溢出錯誤,可是這種我尚未在現實中遇到過。舉個例子,記錄一下吧。class
import java.util.ArrayList; import java.util.List; public class Strings { public static void main(String[] args) { List<String> list = new ArrayList<String>(); int i =1; while(true){ list.add(String.valueOf(i++).intern()); } } }
4:內存直接溢出import
這個不是虛擬機能把控的了,是發生在真實內存中的問題。有一個思路,就是看看代碼中看有沒有使用到NIO的地方。NIO使用的是異步IO,在裏面涉及到直接操做外部內存的操做。能夠看看這方面有沒有什麼問題。