相信大家都知道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;
}
}
}
}