2015-11-12 89 views
0

很少有疑慮的字符串,字符串創作游泳池和堆

當我寫此基礎上,從互聯網上的各種物品我的理解,請原諒我可能是錯的某些語句。

  1. 當我們做 字符串STR1 =新的String( 「newStr1」);。 這會創建2個字符串對象。一個在常規堆中,另一個在字符串池中。爲什麼2個對象及其用法?爲什麼不只是一個游泳池?

  2. 如果我們創建對象爲String str2 = new String(「newStr2」)。intern();。 這將檢查池中是否存在類似的(有意義的相等)對象,並對其進行引用。如果沒有,它會在池中創建一個,但不在堆中?如果是這樣,那麼我們應該使用實習生大部分時間來節省內存?雖然它會影響性能。 所以基本上它是String str2 =「newStr2」;(實習中隱含字符串文字)

  3. 在Java-6之後,字符串池從perm gen空間移動到堆區?所以基本上我們現在只有一個區域堆或者字符串池現在作爲一個單獨的部分堆?如果它不是一個單獨的部分,那麼仍然創建2個對象?

回答

2

只是認爲字符串池是一個特殊的地方來存儲字符串。你可以考慮String池也在堆中(它實際上儘可能地告訴我們),只是小心處理池中的每個值只有一個副本,因此同一個實例可以很容易地被重用(例如當你聲明一個字符串文字)

  1. 因爲它被告知這樣做。 "newStr1"是一個字符串文字,它將在池中創建/查找。 String str1 = new String (...)您正在告訴JVM創建一個String對象的新實例。所以它只是簡單地遵循你告訴它做的事情。當然,JIT可以優化它以避免創建新的實例(它現在正在進行這種優化嗎?),但是您所描述的行爲僅僅是JVM告知要做的事情。

  2. 它只是與上述相同。但是,在new String(...)(它創建了一個新的String對象)之後,您調用了intern(),因此在String池中進行查找。同樣,行爲就是被告知要做的事情。是的,你是對的,在你的情況下,結果與String str1="asdf";一樣,有一些不必要的工作。但是有些情況下,構造函數沒有使用字符串,而您仍然希望強制字符串在字符串池中。在這種情況下,intern()將變得有意義。

  3. 彼爾姆根IS部分堆區域。 (Sun/Oracle pre-8)JVM將堆分成不同的代,並將對象移動到周圍,這會影響對象的GC編輯方式。 PermGen只是堆中從未得到過GC的部分。但是,它仍然是堆的一部分。因此,PermGen與GC算法更相關,您可能注意到,JDK8中不再有PermGen了。

1

在java中如果JVM標識文字(「XYZ」)如果它識別那麼它會創建在堆中的對象它將立即創建字符串常量池,並在同一時間的對象。現在進一步查詢:

1.String str1 = new String(「newStr1」); 這裏爲JVM「newStr1」是文字,所以它將遵循對應於文字的規則,所以它在String常量池中創建一個對象。 new String(「newStr1」) - 這裏對於new運算符,它遵循與new運算符相對應的規則,因此它也會在堆中創建一個對象。

2.intern():這裏實習生不會在pool.interno中創建一個對象,用於改變你的字符串對象來引用字符串池而不是堆。 string s1 = new String(「newStr1」) - 這裏s1將指向堆區而不是字符串常量池。 String s1 = new String(「newStr1」)。intern()將使s1指向字符串常量池,因爲newStr1是在堆和字符串常量池中創建的。 實習生()不會處理字符串對象的創建。

3.permgen:作出有效的垃圾收集堆分成這樣的PermGen中不同的區域也是一個地區,它仍然是唯一里面堆,它裏面heap.please區域是指這個http://www.cubrid.org/blog/dev-platform/understanding-java-garbage-collection/鏈接堆區域。