outofmemory 的幾種狀況

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,在裏面涉及到直接操做外部內存的操做。能夠看看這方面有沒有什麼問題。

相關文章
相關標籤/搜索