不会,再次new以后,上一个al对象丢失引用,会被自动回收的。

解决方案 »

  1.   

    不会,等到垃圾收集起作用时,会收回的,有点浪费,好像垃圾回收还是自己主动做一下,等待系统去回收可能是java运行慢的一个原因
      

  2.   

    为了提高系统运行效率,也可以这样:
    ArrayList al;
    while( true )
            {
                al = new ArrayList();
                ...
            }
      

  3.   

    ===================================
    为了提高系统运行效率,也可以这样:
    ArrayList al;
    while( true )
            {
                al = new ArrayList();
                ...
            }====================================效率更低
      

  4.   

    不会,等到垃圾收集起作用时,会收回的,有点浪费,好像垃圾回收还是自己主动做一下,等待系统去回收可能是java运行慢的一个原因
      

  5.   

    /////////////////////////////////
    ===================================
    为了提高系统运行效率,也可以这样:
    ArrayList al;
    while( true )
            {
                al = new ArrayList();
                ...
            }====================================效率更低
    ////////////////////////////////////to maowu(猫呜) : 能解释一下吗?
      

  6.   

    ArrayList al = new ArrayList();这句好像初始化在对象池里没有具体给他分配存储
    空间所以不会
    答错请谅解 :)  答案仅供参考
      

  7.   

    同意
    sboom(+-LingCh-+)(对不起,爱上你)
    fxywkj(fxywkj)
    的说法,循环结束只有最有一个对象是有reference的
    另外:
    我觉得 变量声明在循环内和循环外是一样的(对于本例)
      

  8.   

    GC不是时时都在作用的,会在适当时候收集,像这样的一个while(true)结构,系统会在内存用尽的时候才去回收的。
      

  9.   


         
    /////////////////////////////////
    ===================================
    为了提高系统运行效率,也可以这样:
    ArrayList al;
    while( true )
            {
                al = new ArrayList();
                ...
            }====================================效率更低
    ////////////////////////////////////to maowu(猫呜) : 能解释一下吗?
    ==============================================================
    理由是最后一个对象更加迟才能被回收。不过这种写法好像也有好处。 
              
      

  10.   


    /////////////////////////////////
    ===================================
    为了提高系统运行效率,也可以这样:
    ArrayList al;
    while( true )
            {
                al = new ArrayList();
                ...
            }====================================效率更低
    ////////////////////////////////////to maowu(猫呜) : 能解释一下吗?
    ==============================================================
    理由是最后一个对象更加迟才能被回收。不过这种写法好像也有好处。 另外一点,《Effective java》中介绍的原则是“让局部变量的作用域尽可能的小”。
      

  11.   

    ArrayList al;
    while( true )
            {
                al = new ArrayList();
                ...
            }while( true )
            {
                ArrayList al = new ArrayList();
            }
    其实这两个生成的byte code都是一样的
      

  12.   

    我来进行一个对比吧:
    //==== 1 ====
    ArrayList al;
    while( true )
            {
                al = new ArrayList();
                ...
            }//==== 2 ====while( true )
            {
                ArrayList al = new ArrayList();
            }在情况2中,每次循环都需要声明一个新的变量,浪费时间,在内存尚未回收的情况下会更多地占用内存。
    而情况1中则只是使用一个变量,没有这些问题。
    而且每进行一次新的循环,上次创建的ArrayList也自动失去引用,同情况1没什么区别。
    对于“最后一个对象更加迟才能被回收”的问题,只需要在循环完成后,加上一句
      al=null;
    即可。
      

  13.   

    package test;import java.util.ArrayList;public class Test88{
    public void foo(){
    ArrayList al;
    while( true ){
                al = new ArrayList();
            }
    } public void bar(){
    while( true ){
                ArrayList al = new ArrayList();
            }
    }
    }javap -c test.Test88public class test.Test88 extends java.lang.Object {
        public test.Test88();
        public void foo();
        public void bar();
    }Method test.Test88()
       0 aload_0
       1 invokespecial #1 <Method java.lang.Object()>
       4 returnMethod void foo()
       0 goto 3
       3 new #2 <Class java.util.ArrayList>
       6 dup
       7 invokespecial #3 <Method java.util.ArrayList()>
      10 astore_1
      11 goto 3Method void bar()
       0 goto 3
       3 new #2 <Class java.util.ArrayList>
       6 dup
       7 invokespecial #3 <Method java.util.ArrayList()>
      10 astore_1
      11 goto 3foo()和bar()是一样的!!
      

  14.   

    to 0xCafeBabe(帅哥也是人~) and All:
    我分别编译了两种情况,代码是这样写的://== 1 ==
    import java.util.*;
    public class Test{
    public static void main(String args[]){
    ArrayList al;
    while( true )
            {
                al = new ArrayList();
            }
    }
    }//== 2 ==
    import java.util.*;
    public class Test{
    public static void main(String args[]){
    while( true )
            {
                ArrayList al = new ArrayList();
            }
    }
    }编译器版本:1.5.0-beta2
    编译的结果:两种情况均为297字节。
    但是进行二进制比较时则有两个字节出现差别。比较结果如下:E:\temp>fc/b 1\Test.class 2\Test.class
    Comparing files 1\Test.class and 2\TEST.CLASS
    0000011A: 07 06
    0000011E: 08 07
      

  15.   

    不一样很正常呀,class文件中可以保存byte code对应src code的line number(行号)以便调试,用javap好了
      

  16.   

    Javac的结果:
    E:\temp\1>javap -c Test
    Compiled from "Test.java"
    public class Test extends java.lang.Object{
    public Test();
      Code:
       0:   aload_0
       1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
       4:   returnpublic static void main(java.lang.String[]);
      Code:
       0:   new     #2; //class java/util/ArrayList
       3:   dup
       4:   invokespecial   #3; //Method java/util/ArrayList."<init>":()V
       7:   astore_1
       8:   goto    0}E:\temp\2>javap -c Test
    Compiled from "Test.java"
    public class Test extends java.lang.Object{
    public Test();
      Code:
       0:   aload_0
       1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
       4:   returnpublic static void main(java.lang.String[]);
      Code:
       0:   new     #2; //class java/util/ArrayList
       3:   dup
       4:   invokespecial   #3; //Method java/util/ArrayList."<init>":()V
       7:   astore_1
       8:   goto    0}
    反编译结果也是一样的。
    但二进制比较为什么出现差别呢?费解ing...另外,字节码的优化方向或许会说明一些问题,可以说明那种想法的方向是对的。
      

  17.   

    回0xCafeBabe(帅哥也是人~)
    =====================
    不一样很正常呀,class文件中可以保存byte code对应src code的line number(行号)以便调试,用javap好了
    =====================嗯,你说得对。
    我用
    javac -g:none Test.java
    又编译了一次,进行二进制比较的结果是无差别。
      

  18.   

    to sboom(+-LingCh-+)(对不起,爱上你)
    等系统用尽内存时候去回收,已经晚了我觉得应该是,"系统判断内存快要用尽的时候"
      

  19.   

    请教0xCafeBabe(帅哥也是人~):
    指令dup和astore_1具体含义是什么?他们如何工作?
      

  20.   

    dup:复制操作数栈顶的一个word,并压入操作数栈astore_1:弹出操作数栈顶的那个word(一个Object引用),保存到局部变量#1看看jvm spec好了
      

  21.   

    aoaoJava(阿峥)
    不要钻我字眼嘛。
      

  22.   

    终极测试:
    源文件:
    import java.util.*;
    public class TestAll{
      public void foo(){
        ArrayList al;
        while( true ){
          al = new ArrayList();
        }
      }  public void bar(){
        while( true ){
          ArrayList al = new ArrayList();
        }
      }
    }编译成class文件后,用jad反编译得到以下结果:// Decompiled by Jad v1.5.8e2. Copyright 2001 Pavel Kouznetsov.
    // Jad home page: http://kpdus.tripod.com/jad.html
    // Decompiler options: packimports(3) 
    // Source File Name:   TestAll.javaimport java.util.ArrayList;public class TestAll
    {    public TestAll()
        {
        }    public void foo()
        {
            ArrayList arraylist;
            do
                arraylist = new ArrayList();
            while(true);
        }    public void bar()
        {
            ArrayList arraylist;
            do
                arraylist = new ArrayList();
            while(true);
        }
    }
      

  23.   

    好像讨论到后来和topic有点出入吗,IMHO, 在本例中arraylist的声明放在循环内外没有任何差别,甚至所谓的推迟最后一个的gc时间根本不存在,这个并不是因为死循环没有最后一个,而是因为对于我们的代码本身而言,gc永远是不可知的,且不可控的。即使是force,gc,具体到哪个垃圾被回收,也是不可知的和不可测的但是我还是觉得,将变量的声明及初始化尽可能推迟这条原则是不会错的