最好能够重用对象,而不是每次需要的时候都需创建一个相同功能的对象。重用方式既快速,又流行。如果对象是不可变的,它就始终可以被重用。
下面是一个比较极端的例子
public static void main(String[] args){
test1();
test2();
}
public static void test1(){
//程序开始时:(先调用一下垃圾回收,但是不一定立即执行)
Runtime.getRuntime().gc();
long initm=Runtime.getRuntime().freeMemory();
for (int i=0;i<100000;i++){
String str1="stringette";
}
//程序结束时:
//Runtime.getRuntime().gc();
long endm=Runtime.getRuntime().freeMemory();
//计算空闲差:
System.out.println(initm-endm);
}
public static void test2(){
//程序开始时:(先调用一下垃圾回收,但是不一定立即执行)
Runtime.getRuntime().gc();
long initm=Runtime.getRuntime().freeMemory();
for (int i=0;i<100000;i++){
String str1=new String("stringette");
}
//程序结束时:
//Runtime.getRuntime().gc();
long endm=Runtime.getRuntime().freeMemory();
//计算空闲差:
System.out.println(initm-endm);
}
很明显可以看出只有一个对象的test1()的内存开销比每次都创建对象的test2()的内存开销少。
所以在创建对象的时候,要考虑是否有可重复使用的对象存在。
在Java 1.5后出现了“自动装箱”,这种方式很容易导致创建多余方法。
public class HideouslySlowProgram {
public static void main(String[] args){
slow();
quit();
}
public static void slow(){
long startTime=System.currentTimeMillis();
Long sum=0L;
for (long i=0;i<Integer.MAX_VALUE;i++){
sum+=i;
}
long endTime=System.currentTimeMillis();
System.out.println("slow:"+(endTime-startTime));
}
public static void quit(){
long startTime=System.currentTimeMillis();
long sum=0L;
for (long i=0;i<Integer.MAX_VALUE;i++){
sum+=i;
}
long endTime=System.currentTimeMillis();
System.out.println("quit:"+(endTime-startTime));
}
}
从上面的代码可以很明显看出这个自动装箱所引起的问题,Long会因为"自动装箱"不停的创建对象,执行效率要比long这种基本类型慢很多。
要优先使用基本类型而不是装箱基本类型,要当心无意识的自动装箱。