2015-09-25 84 views
2

有人問我在interview-問題在堆上創建了多少對象在以下創建:多少String對象都在堆

String s1= "A"; 
String s2= "A"; 
String s3= new String("A"); 

我回答1 - 由於與新的運營商只,創建一個字符串對象。當編譯器遇到s1時,它只會在字符串文字池上創建「A」。而s1和s2指向文字池中相同的文字。但面試官說我的這個游泳池在哪裏?

現在,在一定的博客,我讀:

「在早期版本的Java,我想起來了,到Java 1.6字符串文字池位於堆PermGen的區域,但在Java 1.7更新其感動到主要堆區「。

因此,通過這種方式,所有3個字符串對象都在堆上創建。不是嗎?

但s1和s2指向字符串文字池中相同的文字(s1 == s2爲true),因此當遇到s2時不應創建單獨的對象。所以以這種方式,應該只創建2個對象。

難道有人能夠澄清在堆堆上創建了多少個字符串對象?我錯過了什麼嗎?

回答

0

答案是1,「A」被添加到堆之前任何3線經由String Pool運行,它存在於堆。前兩行引用字符串池中的現有值。第三行強制在堆上創建一個新對象。

這是一個偉大的寫了起來: http://www.journaldev.com/797/what-is-java-string-pool

注:我站在下面的評論糾正。在第1行運行之前,線程池中已經存在「A」,因此第1行實際上沒有添加任何內容。因此,正如您在採訪中所說的那樣,堆的淨更改爲1,因爲只有第3行實際影響堆。

+1

是 - 文章的第一行:「顧名思義,String Pool是存儲在Java堆內存中的字符串池」。遷移到堆的1.7中的更改發生在2011年。 –

+0

第一行沒有向字符串池添加任何內容。 「A」已經存在,因爲該類已加載。它最初由編譯器放入.class文件的字符串池中,並由類加載器合併。 – EJP

+0

謝謝@EJP 5.更新答案以反映更正。應該已經睡了:) –

0

你是對的。一個String對象由String s3= new String("A");創建並放入內存堆中。一個字符串文字"A"將被放入String pool

分配將在堆中,但它仍然會分別存儲字符串文字和分別使用新建立的對象。

在Java的早期版本,我想起來了,到Java 1.6 String pool位於堆permgen area,但在Java 1.7更新其移動到主堆區。由於它在PermGen space之前,因爲其空間非常有限,默認大小爲64 MB,並且用於存儲類元數據(例如, .class文件。創建太多String literals可能會導致java.lang.OutOfMemory: permgen space。現在因爲String pool被移動到更大的內存空間,所以它更安全。

enter image description here

來源:String-literal and String-object

+0

你有什麼參考資料嗎,還是我們應該信任你? –

+0

@JonathonReinhart我已經更新了我的答案。請檢查 – YoungHobbit