2013-02-25 167 views
8

如果您運行下面的代碼會發生什麼情況..關於「新」的關鍵字

while (true) { 
    String x = new String("ABC"); 
} 
在內存方面

Java的內存問題嗎?

字符串x分配在堆棧上還是堆上?程序最終會因內存溢出而崩潰,還是會因垃圾收集而阻止?新關鍵字是否始終在堆上創建對象?何時在堆棧上創建對象?

謝謝!

+1

你可能想看看http://www.xyzws.com/Javafaq/what-is-string-literal-pool/3 – 2013-02-25 09:10:07

+0

嗨,羅漢,請一次提出一個問題。 – MByD 2013-02-25 09:13:49

+0

他們是相關的問題,所以我將它們加在一起,以便我(和其他人)可以對此主題有廣泛的理解! – 2013-02-25 09:15:33

回答

7

是字符串x分配在堆棧上還是堆上?

x不是String。它是對String的引用。該引用是一個局部變量,因此在棧上。 String是一個對象,因此會堆積如山。

會將程序崩潰,最終因爲內存溢出

大概不會的。

還是會垃圾回收阻止?

它應該。

新的關鍵字是否總是在堆上創建對象?

是的。

何時在堆棧上創建對象?

永遠......除非JVM決定它不能逃避當前的範圍,所以決定這樣做。

+0

+1尼斯的答案與解釋。 :) – 2013-02-25 09:26:37

+1

不完全是我的專業領域 - 但是在這種情況下,對象不能逃避當前範圍並因此導致字符串被分配到堆棧上嗎? – mikera 2013-02-25 09:26:45

+0

是的,程序不會崩潰,我一直運行這個片段很長時間,但程序仍在運行。很好的答案! (+1) – asifsid88 2013-02-25 09:27:28

2

使用新的,是的,把對象放在堆上。不能被任何線程訪問的對象可以被垃圾回收。無論內存是否耗盡,都取決於程序使用的數據大小,如果擅長「釋放」對象,則不需要更多內存(請考慮:內存泄漏很糟糕)。

在你的例子中,你會像瘋了一樣運行垃圾回收器,我認爲這是你打算演示的。

局部變量進入堆棧。

-1

理論上,new在堆上創建,並且在堆上創建非對象(即,int s,char s等)。唯一的例外,afaik,也是在堆棧上創建的字符串。實際上,許多現代JVM的JIT編譯器將會看到,在某些情況下,可以在堆棧上創建使用new創建的對象(例如,未在當前函數外引用的本地對象)。

垃圾收集器將負責解除您的分配,這是它的目的,但是當然如果您在同一時間創建並保留對太多對象的引用,則可能會導致內存不足(嘗試使用十億字符串,例如)。

+0

堆棧中的字符串沒有例外。 – EJP 2013-02-25 09:27:16