http://clarkht.iteye.com/blog/482644
String oldStr = "hello,clark";
String newStr = oldStr.subString(0,4);
對於這個寫法,實際上對於oldStr是一個char[]數組[h,e,l,l,0,,,c,l,a,r,k],對於subString操作,newStr並不是自己copy oldStr的char[]數組hello自己去建立一個新的char[]數組,而是java在背後進行了String Reusing Optimization,它不會自己建立一個新的char數組,而是reuse原來的char數組。所以了,這樣就不會有很多的原來的char[]數組的片段。引用http://www.javablogging.com/string-and-memory-leaks/ 上的列子:
Java代碼
public static void sendEmail(String emailUrl) {
String email = emailUrl.substring(7); // 'mailto:' prefix has 7 letters
String userName = email.substring(0, email.indexOf("@"));
String domainName = email.substring(email.indexOf("@"));
}
public static void main(String[] args) {
sendEmail("mailto:user_name@domain_name.com");
}
但是這個雖然在一般情況是好,不過也是有代價的。根據http://nflath.com/2009/07/the-dangers-of-stringsubstring/上,因為字串不是自己建立一個char[]數組,而是引用了原來的char[]數組,這樣oldStr就無法garbage collected ,因為newStr還是擁有oldStr的char[]數組的引用。這樣容易引起Outof Memory 異常。解決辦法是了,便是讓newStr擁有自己的char[]數組,也就是自己在subString時強迫建立自己的char[]數組,這樣就不會有garbage collected 的問題(reachable but unused!) 怎麼辦:
Java代碼
String sub = new String( oldString.substring(0, 4) );
---------------------------------------------------------------
為了避免記憶體拷貝、加快速度,Sun JDK直接複用了原String對象的char[],位移量和長度來標識不同的字串內容。也就是說,subString出的來String小對象仍然會指向原String大對象的char[],split也是同樣的情況 。這就解釋了,為什麼HashMap中String對象的char[]都那麼大。
-------------------------------------------------------
可以參考:
http://jarfield.iteye.com/blog/583946