1.循环内声明对象for(int i = 0;i < len ; i ++){
  Object o = new Object();
}2.循环外声明对象Object o = null;
for(int i = 0;i < len ; i ++){
  o = new Object();
}
大家都用哪种方式的?
哪个的运行效率高,
从垃圾回收方面看,哪个比较好

解决方案 »

  1.   

    jvm可以做出很多优化的,这个事情说不好
      

  2.   

    其实没什么差别的,给如下一个例子你可能就知道了public void dot1(){
        for(int i=0;i<100;i++){
             dot2();
        }
    }public void dot2(){
        int i = 0;
        Object obj = new Object();
        //more....
    }在dot1的循环中,不断要调用方法dot2,这个应该是很容易理解的常见现象吧。然后在dot2中又会定义多个变量并新建实例。如果dot2只为dot1服务,那这和在dot1的for循环中直接new 变量没什么差别。
    还有,sun的程序员也是这么用的。在for 或者 while中new 对象。可以去jdk source中去找一下。
      

  3.   

    从理论上来说,是这样的,不过JVM内部是否优化了很难说,也就是说第一种情况JVM也可能只使用一个临时变量,因为当临时变量离开for的花括号时生命周期就结束了,这时JVM是可以判断回收不回收临时变量,所以,很难说JVM不会优化,循环使用已经生命周期结束的内存地址,也就是说没有所谓的1W个临时变量了,因为使用的都是同一块内存地址。而第二种情况,当for循环结束后,因为临时变量生命周期没有结束,所以会一直占用内存,直到离开生命周期作用域。
    所以,主要还是看你的循环体内部的处理逻辑,如果只是这样简单的一条语句,还真不好说。
      

  4.   


    我刚才又发现了另一个相关的问题,如果采用这种方式
    for(int i ;;) { Object obj = new Object(i++);}//注意一个死循环obj占用栈内存,new 出来的这个Object占用堆内存。
    当死循环运行到一个较长时间后,如果在整个for期间,有无穷多个obj存在的话,那它将在栈中占用无穷多地址;同时每个obj将指向堆中对应的一个new出来的Object();那么这样有一个问题,在此for期间,在堆中new 的Object() 总有一个obj引用他,直到for结束。而本例中for不可能结束,也就是堆中永远new Object();栈中永远为obj分配地址。直到一个时间,应该以生堆或栈溢出的情况。然而,本人在运行以上实例时,并没有发现有堆或栈溢出的情况,操作系统为此虚拟机分配的内存总是在涨了4个字节后,又收回4个字节。 于是,本人判断,收回4个字节是不是垃圾回收机制收回了堆中new出来的Object(),因为栈不存在回收的问题,所以说堆中new出来的Object()在一定时间后,总有一总分不存在引用才被GC,此现像是否说明栈中的obj不存在无穷多外占用资源的问题(生成obj临时变量)。
    以上现象,欢迎高手指正!
      

  5.   

    更正一下上实例中的语法:
    for(int i=0 ;;) { Object obj = new Object(i++);}//注意一个死循环
      

  6.   

    喜欢瞎猜的人还是占大多说。
    javap 处理一下,看栈空间占多少。
      

  7.   


    public class A{
      public static void main(String[] args){
        Object m = null;
        for(int i = 1; i < 100; i ++){
          m = new Object();
        }
        for(int i = 1; i < 100; i ++){
          Object o = new Object();
        }
      }
    }
    用javap的结果D:\>javap -c A
    Compiled from "A.java"
    public class A extends java.lang.Object{
    public A();
      Code:
       0:   aload_0
       1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
       4:   returnpublic static void main(java.lang.String[]);
      Code:
       0:   aconst_null    /*循环外开始*/
       1:   astore_1
       2:   iconst_1
       3:   istore_2
       4:   iload_2
       5:   bipush  100
       7:   if_icmpge       24
       10:  new     #2; //class java/lang/Object
       13:  dup
       14:  invokespecial   #1; //Method java/lang/Object."<init>":()V
       17:  astore_1
       18:  iinc    2, 1
       21:  goto    4
       24:  iconst_1      /*循环内开始*/
       25:  istore_2
       26:  iload_2
       27:  bipush  100
       29:  if_icmpge       46
       32:  new     #2; //class java/lang/Object
       35:  dup
       36:  invokespecial   #1; //Method java/lang/Object."<init>":()V
       39:  astore_3
       40:  iinc    2, 1
       43:  goto    26
       46:  return}
    结果就是,循环外的还比循环内的多了0和1两条指令