2014-10-20 47 views

回答

2

你在正確的軌道上。您可以用盡堆內存,但它不稱爲HeapOverflow。它被稱爲OutOfMemoryError。 雖然HeapOverflow聽起來很吸引人,但它並不是那樣稱呼它的,因爲堆通常有自由分配的區域。另一方面,堆棧只有兩個區域,免費和分配。當您在堆棧上分配更多分配時,分配的區域會擴展到空閒區域。因此你最終溢出堆棧。更多關於堆棧vs堆here

這裏是用盡堆內存的一個例子:

public class RunOutOfMemory { 
    public static void main(String[] args){ 
     System.out.println("Haven't tried to allocate lots of heap memory."); 
     int[][] matrix = new int[100000][100000000]; 
     System.out.println("A miracle occured."); 
    } 
} 

劇透:你需要約4 TB的內存奇蹟發生

0

如果你的Java試圖分配一個對象時運行的堆空間不足,你會得到一個OutOfMemoryError

http://docs.oracle.com/javase/7/docs/api/java/lang/OutOfMemoryError.html

雖然對象是在堆內存初始化不應該堆內存溢出錯誤是因爲涉及一個對象來調用該方法而拋出。

如果您有一個無限遞歸函數,它也會從堆中分配一個對象,那麼可能會首先獲取OutOfMemoryError。這取決於對象分配的大小以及堆和堆棧的大小。

4

如果您

  • 您的堆棧大小不夠大,和/或
  • 堆大小足夠小,

你會得到一個堆溢出錯誤(java.lang.OutOfMemoryError),而不是堆棧溢出錯誤(java.lang.StackOverflowError)。

您通常看不到此行爲的原因是,默認情況下(取決於JVM),堆棧大小比堆大小小很多,因此堆棧會先運行。

您可以通過創建遞歸方法並使用不同的堆和堆棧大小來嘗試。例如,以下內容將執行MyClass,堆大小爲2MB,堆棧大小爲4MB。如果調用MyClass執行涉及對象創建的無限遞歸方法,則在運行到StackOverflowError之前,您必然會遇到OutOfMemoryError

java -Xms2m -Xmx2m -Xss4m MyClass