首先要說的是垃圾收集不會立即發生。因此,分配null
任何東西不會/不能導致垃圾回收。什麼是可能確實會導致一個對象變爲無法訪問 ...並且這將使其成爲未來GC運行中垃圾收集的潛在候選者。
現在給你具體的例子。
重要說明:以下只適用於適用於較舊的JVM;即Java 7 update 5及更早的版本。在Java 7更新6中,他們更改String.substring()
,以便目標字符串和生成的子字符串不共享後備數組。這消除了substring
的潛在存儲泄漏問題。
的substring
方法不把參照原字符串的新的String。它實際上做的是保存對原始String的後備數組的引用;即包含字符的陣列。
但話雖如此,將null
分配到samplel
是不足以使整個原始字符串的狀態無法訪問。原始字符串的整個支持數組將保持可到達......這意味着它不會成爲垃圾收集的候選人。
但還有另一個複雜因素。您可以設置sample1
爲字符串文字,並表示一個字符串文字String對象是總是到達(除非整個班級被卸載!)
但通過顯式定義樣品1爲空,將樣本1和樣本2是可用於垃圾收集?
原始sample1
對象將保持完全可達的,並且sample2
仍將是可達的,除非該變量超出範圍。
如果sample1
不是文字,也沒有其他引用,那麼答案會不同。 sample1
對象將無法訪問,但其後備陣列仍可通過sample2
到達。
在第二個示例中,複製子字符串會導致創建新的字符串。並且保證新的String不會與原始String和臨時子字符串共享後備數組。在這種情況下,分配null
是不必要的。
現在是否將sample1和sample2都用於垃圾回收?
對於sample1
是文字的情況,答案與上述相同。
如果sample1
不是文字,並且沒有其他引用,則sample1
和臨時子字符串現在將無法訪問。
我只是想知道哪裏String構造是有幫助的。
理論上它會是。
在實踐中,它取決於GC最終是否可以繼續查找時是否仍然可以訪問引用......以及所討論的字符串是否足夠大並且足夠多以對內存使用量產生重大影響。
而且在實踐中,前提是通常不滿意,創造一個新的字符串像通常於事無補。
他使用術語「可用於垃圾回收」是正確的:很明顯,OP知道垃圾回收不會立即發生,並且這一事實不會影響實際問題, 對? – 2013-04-07 01:45:15
@NathanielFord - 我不清楚他是否理解這些詞的意思。我選擇以不能理解的方式回答問題。而且還讓其他錯過/不瞭解這一點的人也能理解答案。 – 2013-04-07 01:55:35
@Suraj - 如果有線程訪問或能夠訪問一個對象,那麼它是可訪問的。這基本上是可達性意味着什麼。 – 2013-04-07 02:34:59