Java 在给定的程序中,垃圾收集器在对象被解引用之前运行…使用jre 7(32位)

Java 在给定的程序中,垃圾收集器在对象被解引用之前运行…使用jre 7(32位),java,garbage-collection,Java,Garbage Collection,在从rajni1第一个对象解除robot1之前,终结器如何运行。。。 循环在无限循环中运行 我知道垃圾收集器在堆空间不足时运行,并且对象分配需要更多内存…但条件是内存中必须有一些未引用的对象 --->在jre 32位中运行以获得给定的输出。。。您最好知道原因???现在您已经提供了输出,这就更清楚了 您可以查看编译后的字节码以了解原因 class Robot { long memory[] = new long[9923372]; private String name; Robot(Stri

在从rajni1第一个对象解除robot1之前,终结器如何运行。。。 循环在无限循环中运行

我知道垃圾收集器在堆空间不足时运行,并且对象分配需要更多内存…但条件是内存中必须有一些未引用的对象


--->在jre 32位中运行以获得给定的输出。。。您最好知道原因???

现在您已经提供了输出,这就更清楚了

您可以查看编译后的字节码以了解原因

class Robot
{
long memory[] = new long[9923372];

private String name;

Robot(String nm) throws Exception
{
name = nm;
System.out.println("name = " + name);
}

protected void finalize()
{
System.out.println("\nBye - Bye ---eeeee " + name+"\n");
}

}


class Test
{

public static void main(String sdf[]) throws Exception
{
int i=1;
Robot robot1;


while(true)
{
//finalizer runs before the dereference of rajni - 1
robot1= new Robot("Rajni - "+i++);
Thread.sleep(1000);
}

}
}
publicstaticmain([Ljava/lang/String;)V抛出java/lang/Exception
L0
线路号48 L0
ICONST_1
史前1
L1
行号54 L1
帧附加[I]
新的主机器人
重复
新java/lang/StringBuilder
重复
调用特殊的java/lang/StringBuilder。()V
“拉贾尼”最不发达国家
invokeVirtualJava/lang/StringBuilder.append(Ljava/lang/String;)Ljava/lang/StringBuilder;
伊洛德1号
IINC 1
invokeVirtualJava/lang/StringBuilder.append(I)Ljava/lang/StringBuilder;
invokeVirtualJava/lang/StringBuilder.toString()Ljava/lang/String;
INVOKESPECIAL Main$Robot.(Ljava/lang/String;)V
阿斯托尔2号
L2
行号55 L2
最不发达国家1000
invokestaticjava/lang/Thread.sleep(J)V
转到L1
L3
LOCALVARIABLE sdf[Ljava/lang/String;L0 L3 0
本地变量i L1 L3 1
本地变量robot1 LMain$Robot;L2 L3 2
MAXSTACK=4
最大局部变量=3
需要注意的重要一行是
robot1
变量的范围,该变量介于
L2
L3
之间,即仅在
线程睡眠(1000);
期间,只要循环跳回到
L1


这意味着实际上,变量可以在循环的顶部进行GC编辑,而不是像您想象的那样在新机器人创建之后进行GC编辑。

请显示程序输出。您所说的“取消引用之前”是什么意思?你从未引用过
机器人1
,因此它可能甚至没有生成,而
新机器人
只是简单地扔在地板上--可以立即收集。我无法很好地解释…只是看到输出…你会在第一个对象(rajni-1)取消引用之前看到…gc运行…并删除第一个对象..甚至robot1也引用了对象rajni1(顺便说一句,在计算中,“取消引用”意味着“跟随”指针或对其“目标”的引用)您的输出显示了一个对象的构造序列,然后是同一对象的终结。这里没有证据表明取消引用是何时发生的。您还需要知道终结器运行在一个单独的线程上,并且写入同一流的不同线程可能由于缓冲而以意外的方式交错。没有理由回答。@nihal更新了我的答案。你能告诉我如何像上面那样分解字节码以查看变量的作用域吗…@nihal你可以做
javap-c-v-p-cp{classpath}mypackage.MyClass
或者您可以在IDE中添加一个字节码查看器。ASM字节码查看器非常好。->如果我指定robot1=null,那么在声明时会出现一个有趣的事情-OutOfMemoryError,垃圾收集器不会运行…这有点令人困惑…这样做会增加它的范围吗…您认为呢???
  public static main([Ljava/lang/String;)V throws java/lang/Exception 
   L0
    LINENUMBER 48 L0
    ICONST_1
    ISTORE 1
   L1
    LINENUMBER 54 L1
   FRAME APPEND [I]
    NEW Main$Robot
    DUP
    NEW java/lang/StringBuilder
    DUP
    INVOKESPECIAL java/lang/StringBuilder.<init> ()V
    LDC "Rajni - "
    INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;
    ILOAD 1
    IINC 1 1
    INVOKEVIRTUAL java/lang/StringBuilder.append (I)Ljava/lang/StringBuilder;
    INVOKEVIRTUAL java/lang/StringBuilder.toString ()Ljava/lang/String;
    INVOKESPECIAL Main$Robot.<init> (Ljava/lang/String;)V
    ASTORE 2
   L2
    LINENUMBER 55 L2
    LDC 1000
    INVOKESTATIC java/lang/Thread.sleep (J)V
    GOTO L1
   L3
    LOCALVARIABLE sdf [Ljava/lang/String; L0 L3 0
    LOCALVARIABLE i I L1 L3 1
    LOCALVARIABLE robot1 LMain$Robot; L2 L3 2
    MAXSTACK = 4
    MAXLOCALS = 3