2013-10-23 82 views
0

由於嵌套的構造函數調用,我有以下代碼及其引發的StackOverflowException,並且我知道只有在構造函數成功運行時才分配內存。爲什麼這段代碼拋出StackOverflowException而不是OutOfMemoryException?

package interview; 

public class StackOverflow { 
    int i; 
    StackOverflow() 
    { 
      System.out.println(" i= "+i); 
     System.out.println("in Constructor"); 
     StackOverflow sOf = new StackOverflow(); 
     sOf.i=5; 
     System.out.println(" i= "+i); 
    } 
    public static void main(String[] args) { 
     System.out.println("in main"); 
     StackOverflow s = new StackOverflow(); 
     s.i=10; 
     System.out.println(" i= "+s.i); 
    } 

} 

所以我懷疑這裏發生了什麼'i'的價值?它被存儲在棧或堆的某個地方嗎? 在這種情況下,上面的代碼可以拋出以下異常?

OutOfMemoryException

+1

http://ankackoverflow.com/questions/11435613/whats-the-difference-between-stackoverflowerror-and-outofmemoryerror – Trying

+0

@ankit - 你的問題標題和描述的實際問題是完全不同的。此外,如果您在回答發佈到您的問題後更改問題,它會使答案海報混淆不清。請不要這樣做。 – SudoRahul

+0

@ R.J感謝您的建議,我會照顧到這一點。但在最初的問題中,我也提到過我的價值 – ankit

回答

3

的OutOfMemoryError:時,因爲它超出了內存,並且可以通過垃圾收集器提供任何更多的內存,Java虛擬機無法分配一個對象時拋出。

StackOverflowError:由於應用程序遞歸太深而發生堆棧溢出時發生。

in which case it can throw OutOfMemoryError?

  • 你的構造函數遞歸調用自己進入更深層, 堆棧溢出之前JVM是內存不足。

    而不是遞歸使用for循環來創建太多的對象。您 也許能夠看到OutOfMemoryError

My question is what is happening to the value of i(it is getting stored heap or stack):

  • JVM specification-2.5.2明確指出:

    A Java Virtual Machine stack is analogous to the stack of a conventional language such as C: it holds local variables and partial results, and plays a part in method invocation and return.

    由於堆存儲對象和i是你 StackOverflow類的字段成員,它被保存在Heap

+0

多數民衆贊成在正確的,我知道,但我的問題是在這裏發生的價值,我得到了存儲堆或堆棧。 – ankit

+0

它是堆,因爲它是一個成員字段。 – Sage

+0

@ankit'i'將始終爲0 – Trying

0

當您啓動JVM時,您可以定義可以使用多少RAM用於處理。 JVM分爲其處理目的某些存儲器位置這一點,其中的兩個是Stack & Heap

OutOfMemoryError涉及堆。如果你在memeory中有大對象(或)被引用的對象,那麼你會看到OutofMemoryError

StackOverflowError與堆棧有關。你所有的局部變量和方法調用相關的數據都將被放在堆棧中。對於每個方法調用,將創建一個堆棧幀,並將本地以及方法調用相關數據放入堆棧幀內。一旦方法執行完成,堆棧幀將被刪除。一種方法來重現這一點,方法調用有無限循環,你會看到stackoverflow錯誤,因爲堆棧幀將填充每個調用的方法數據,但它不會被釋放(刪除)。

在你的情況下,你正在調用造成棧溢出而不是堆的構造函數,因此得到StackOverflowError而不是OutOfMemoryError

StackOverflow() 
    {       
     StackOverflow sOf = new StackOverflow(); //causing Stack to overflow.**      
    } 

i的值將總是0即默認值。

請參考this

1

每當您調用另一個函數內的函數時,第二個函數將出現在堆棧的頂部。既然你已經對你的構造函數進行了遞歸調用,它會不斷增加你的堆棧大小,因爲你的新構造函數。當沒有剩餘空間在主堆棧,JVM中輸入StackOverflowException時,將創建新的構造函數條目。

對於OutofMemoryException,你只需要創建儘可能多的對象,儘可能多的可能的大小,沒有留在你的空間。

Class variables and Objects are created in Heap and function calls, and local variables are maintained in Stack.

iclass variable,因此它獲得存儲在Heap。並且由於它在聲明時沒有被定義,它將得到int的默認值,即0。您的構造函數永遠不會到達將值5指定爲i的行。所以它總是有值0

2

當您啓動JVM時,會從操作系統分配一些內存給它。 jvm使用這個內存來處理它的purpuses。 JVM以多種方式使用這些內存 - 比如堆棧和堆。

每當調用某個方法時,該方法中的參數,返回值和其他局部變量等數據將保存在堆棧中。該方法被調用時創建,並在方法完成時被銷燬。如果你繼續從一個方法中調用一個方法,那麼就會出現瓶頸發生的地方,它會向你顯示一個StackOverFlowError。但是在堆的情況下 - JVM從這個堆中爲新對象分配內存。如果您有對象的引用,並且堆中剩餘的空閒空間非常少,則會向您顯示OutOfMemoryError。

相關問題