2016-06-21 99 views
3

產生雙引號,我嘗試執行下面的代碼行生成。我的理解是#1和#2都應該在字符串池中生成字符串,因此在執行過程中不應該有任何區別,但是當我分析堆轉儲時,如果在字符串池中生成intern()字符串(可以通過有限數量的字符串對象來解釋),但是在堆上生成#1字符串的情況下(因爲堆轉儲中存在大量字符串對象),並且系統比以前的情況快。有人可以解釋爲什麼它是這樣嗎?我正在使用Java 6來執行下面的代碼行。萬一字符串中使用沒有得到的字符串池

import java.util.LinkedList; 

public class LotsOfStrings { 

private static final LinkedList<String> LOTS_OF_STRINGS = new  LinkedList<String>(); 

public static void main(String[] args) throws Exception { 
    int iteration = 0; 
    while (true) { 
     for (int i = 0; i < 100; i++) { 
      for (int j = 0; j < 1000; j++) { 
       String s= "String " + j; 
       LOTS_OF_STRINGS.add(s); // #1 
       //LOTS_OF_STRINGS.add(new String("String " + j).intern()); //#2 
      } 
     } 
     iteration++; 
     System.out.println("Survived Iteration: " + iteration); 
     Thread.sleep(100); 
    } 
} 

堆轉儲對象的截圖,如果在的情況下,實習生 intern

堆轉儲對象截圖#1

string

+0

字符串僅當它的可用池接到一個字符串池參考否則其創造堆的字符串。 – Nir

+0

在內環它應產生的第一執行1000唯一字符串字符串0 .... ....到字符串999。在此之後,應在內部循環的所有後續執行作爲第一字符串執行期間創建的不是程序使用的參考參考應該在字符串池中可用? – Vyas

回答

1

如果創建一個字符串沒有實習它,它只是去堆。所以可以有多個相同字符串的副本。如果您在字符串中實習,每個相等類將只有一個字符串。

爲相同的j多次創建字符串"String" + j更多的內存消耗,沒有實習字符串。

實習節省內存,但因爲每個字符串在某種HashSet的召開和創建一個字符串意味着仰視,如果它已經存在於HashSet的存在還可以減慢程序。

注:某些字符串自動扣留,例如源代碼中的字符串文字。

+1

你是否將字符串創建爲String s =「Nothing」;不會在字符串池中自動創建?我的理解是,如果一個字符串是使用new運算符創建的(String s = new String(「nothing」)),它將在堆上創建,並且如果使用雙引號創建字符串(String s =「nothing」),它將由默認情況下在permgen空間的字符串池中創建。使用intern()調用字符串可以將字符串從堆移到字符串池。如果事情是不正確的在我的理解 – Vyas

+1

最多據我所知,一個字符串僅自動,如果它是一個編譯時間常數(其中「串」 + j不)拘留請指正。如果我錯了,請指點適當的來源。 –

+0

這是我沒有意識到一個字符串需要編譯時間常量才能在字符串池中生成。感謝您的幫助。 – Vyas