相信大家都知道String和StringBuffer之間是有區別的,但究竟它們之間的區別在哪裏下面就在本小節中一探究竟,看看能給我們些什麼啓示。還是剛纔那個程序,把它改一改,將本程序中的String進行無限次的累加,看看什麼時候拋出內存超限的異常,程序如下所示。
public class MemoryTest{
程序運行後,果然不一會兒的功夫就報出了異常。 可以注意到,在String的實際字節數只有8MB的情況下,環後已佔內存數竟然已達到了63.56MB。這說明,String這個對象的實際佔用內存數量與其自身的字節數不相符。於是,在環19次的時候就已報OutOfMemoryError的錯誤了。 因此,應該少用String這東西,特別是 String的“+=”操作。不僅來的String對象不能繼續使用,而且又要產生多個新對象,會較高的佔用內存,所以必須要改用StringBuffer來實現相應目的。下面是改用StringBuffer來做的測試。
public class MemoryTest{
public static void main(String args[]){
StringBuffer s=new StringBuffer("abcdefghijklmnop");
System.out.print("當前虛擬機最大可用內存爲:");
將String改爲StringBuffer以後,在運行時得到了如下結果, 這次可以發現,當StringBuffer所佔用的實際字節數爲16M的時候才產生溢出,整整比上一個程序的String實際字節數8MB多了一倍。
System.out.println(Runtime.getRuntime().maxMemory()/1024/1024+"M");
System.out.print("環前,虛擬機已佔用內存:");
System.out.println(Runtime.getRuntime().totalMemory()/1024/1024+"M");
int count = 0;
while(true){
try{
s.append(s);
count++;
}
catch(Error o){
System.out.println("環次數:"+count);
System.out.println("String實際字節數:"+s.length()/1024/1024+"M");
System.out.println("環後,已佔用內存:");
System.out.println(Runtime.getRuntime().totalMemory()/1024/1024+"M");
System.out.println("Catch到的錯誤:"+o);
break;
}
}
}
}
public static void main(String args[]){
String s="abcdefghijklmnop";
System.out.print("當前虛擬機最大可用內存爲:");
System.out.println(Runtime.getRuntime().maxMemory()/1024/1024+"M");
System.out.print("環前,虛擬機已佔用內存:");
System.out.println(Runtime.getRuntime().totalMemory()/1024/1024+"M");
int count = 0;
while(true){
try{
s+=s;
count++;
}
catch(Error o){
System.out.println("環次數:"+count);
System.out.println("String實際字節數:"+s.length()/1024/1024+"M");
System.out.print("環後,已佔用內存:");
System.out.println(Runtime.getRuntime().totalMemory()/1024/ 1024+"M");
System.out.println("Catch到的錯誤:"+o);
break;
}
}
}
}