Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/381.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 删除引用后GC不会从数组中删除对象_Java_Garbage Collection - Fatal编程技术网

Java 删除引用后GC不会从数组中删除对象

Java 删除引用后GC不会从数组中删除对象,java,garbage-collection,Java,Garbage Collection,我有一个班形状: private int refcount = 0; private static long counter = 0; private final long id = counter++; Shape () { System.out.println("Create "+ this); } public void addRef() { refcount++; } public void dispose() { if (--refcount == 0)

我有一个班形状

private int refcount = 0;
private static long counter = 0;
private final long id = counter++;
Shape () {
    System.out.println("Create "+ this);
}

public void addRef() { refcount++; }
public void dispose() {
    if (--refcount == 0)
        System.out.println("Delete " + this);
}

@Override
public String toString() { return "Shape "+ id; }

@Override
public void finalize() {
    if (refcount == 0)
        System.out.println("Finalize correctly " + this);
}
private Shape shape;
private static long counter = 0;
private final long id = counter++;
Container (Shape shape) {
    this.shape = shape;
    this.shape.addRef();
    System.out.println("Create " + this );
}


public void dispose() {
    System.out.println("Delete " + this);
    shape.dispose();
}

@Override
public String toString() { return "Container "+ id; }

@Override   
public void finalize() { System.out.println("Finalize container!"); }
和第二类集装箱:

private int refcount = 0;
private static long counter = 0;
private final long id = counter++;
Shape () {
    System.out.println("Create "+ this);
}

public void addRef() { refcount++; }
public void dispose() {
    if (--refcount == 0)
        System.out.println("Delete " + this);
}

@Override
public String toString() { return "Shape "+ id; }

@Override
public void finalize() {
    if (refcount == 0)
        System.out.println("Finalize correctly " + this);
}
private Shape shape;
private static long counter = 0;
private final long id = counter++;
Container (Shape shape) {
    this.shape = shape;
    this.shape.addRef();
    System.out.println("Create " + this );
}


public void dispose() {
    System.out.println("Delete " + this);
    shape.dispose();
}

@Override
public String toString() { return "Container "+ id; }

@Override   
public void finalize() { System.out.println("Finalize container!"); }
这是我的简单主代码:

public static void main(String[] args) {
    System.out.println("Start");
    Shape sh = new Shape();
    Container[] cont = { new Container(sh), new Container(sh), new Container(sh) };
    for (Container c : cont)  
        c.dispose();           
    cont = null;
    System.gc();
    System.out.println("Finish");
}
我想知道,为什么我没有得到评论“Finalize container!”?删除行时:

    for (Container c : cont)
        c.dispose();

程序工作正常-我收到了3次“Finalize container”注释。

System.gc()不能保证完整的gc,它只是对JVM的一个尽最大努力的建议,不要指望它。

嗯,您仍然有一个对形状的引用。你为什么要处理这件事?与终结有关的任何事情都是一个相当决定性的指标,表明您的代码存在问题。为什么您需要对引用进行如此精确的“控制”?在绝大多数情况下,您可以(也应该)让GC来处理这件事,而不是试图阻止它,例如通过调用
System.GC()
(可能曾经)我知道,但我不明白为什么我有引用?我也知道最终定稿经常会有问题,但我不知道还有什么其他方法可以检查我的对象是否被删除。但是为什么你需要知道呢?专注于编写好的代码,这已经够难了。VM和GC在处理内存方面比95%的Java开发人员更出色,除非您正在处理实时交易应用程序。您可以节省大量代码^^。此外,如果您以后确实检测到内存问题,探查器既便宜又易于使用。@AndrewRegan JVM和GC工作得很好,我不想改进它们。我想看看我是否正确管理引用。如果结果是一样的,我不担心,但不同的结果让我吃惊