這是一個我們難以理解的問題。用文字描述它很困難,但我希望能夠理解這個要點。java中保留的字符串堆大小
我知道一個字符串的實際內容被包含在一個內部char數組中。在正常情況下,字符串的保留堆大小將包含40個字節加上字符數組的大小。這是解釋here。當調用子字符串時,字符數組保留對原始字符串的引用,因此字符數組的保留大小可能比字符串本身大得多。
但是使用Yourkit或MAT一些奇怪的剖析內存使用情況時似乎發生。引用char數組保留大小的字符串不包含字符數組的保留大小。
一個示例可以是如下的(半僞代碼):
String date = "2011-11-33"; (24 bytes)
date.value = char{1172}; (2360 bytes)
字符串的保留大小被定義爲24個字節,而不包括字符陣列的保留尺寸。如果由於許多子字符串操作導致字符數組引用很多,這可能是有意義的。
現在,當此字符串被包括在某些類型的集合,諸如數組或列表然後此陣列的保留尺寸將包括所有的字符串包含字符陣列的保留尺寸的保留尺寸。
然後我們有一個情況是這樣的:
Array's retained size = 300 bytes
array[0] = String 40 bytes;
array[1] = String 40 bytes;
array[1].value = char[] (220 bytes)
你因此不得不考慮每個數組項,試圖找出其中保留的大小來的。
再次,這可以解釋在該陣列擁有所有持有到相同的字符數組的引用,並且因此完全陣列的保留大小是正確的琴絃。
現在我們來解決這個問題。
我保持在一個單獨的目的是,我上面討論的陣列以及一個不同的陣列使用相同的字符串的引用。在這兩個數組中,字符串都指向相同的字符數組。這是預料之中 - 畢竟我們在談論同一個字符串。然而,這個字符數組的保留大小在這個新對象中被計數。換句話說,保留的大小似乎是雙倍的。如果我刪除第一個數組,那麼第二個數組仍將保存對字符數組的引用,反之亦然。這導致了一個混亂,因爲它看起來像java持有兩個單獨的引用到相同的字符數組。怎麼會這樣?這是Java內存的問題,還是隻是分析器顯示信息的方式?
這個問題在試圖追查在我們的應用程序巨大的內存使用造成了很大的麻煩我們。
再次 - 我希望有人在那裏就能明白的問題,並解釋。
感謝您的幫助
我將下載jprofiler的評估,看看它是否更有意義。儘管感謝您的回答。它看起來更有意義...... – slbruce
不幸的是我發現jprofiler非常難以使用。我沒有時間學習如何充分發揮它的潛力,所以我只會說出你的看法:)感謝您的幫助 – slbruce
爲了表示您的讚賞,您可以接受我的回答:-)讓我向你保證JProfiler根本不難使用。對於上面的例子,你只需要一個堆快照,選擇包含數組的類並激活「最大對象」視圖。 –