Java 这会导致内存泄漏吗?

Java 这会导致内存泄漏吗?,java,memory-leaks,anonymous-class,Java,Memory Leaks,Anonymous Class,我最近读了一些帖子/答案,建议使用匿名类可能导致内存泄漏。如果我理解正确,如果一个匿名类的对象引用泄漏到封闭类之外,这可能会导致该匿名类实例成为不可回收的垃圾 为了确保我理解正确,我说下面的示例代码不会导致内存泄漏,对吗 public class EnclosingClass { private AnonymousClassBase anonymous; public void startDoingSomething() { this.anonymous = n

我最近读了一些帖子/答案,建议使用匿名类可能导致内存泄漏。如果我理解正确,如果一个匿名类的对象引用泄漏到封闭类之外,这可能会导致该匿名类实例成为不可回收的垃圾

为了确保我理解正确,我说下面的示例代码不会导致内存泄漏,对吗

public class EnclosingClass {
    private AnonymousClassBase anonymous;

    public void startDoingSomething() {
        this.anonymous = new AnonymousClassBase() {
            @Override public void anonymouslyDoSomething() {
                EnclosingClass.this.doSomething("Did something anonymously!");
            }
        };
        this.anonymous.anonymouslyDoSomething();
    }

    private void doSomething(final String something) {
        System.out.println(something);
    }
}

public abstract class AnonymousClassBase {
    public abstract void anonymouslyDoSomething();
}

public class MainClass {
    private final EnclosingClass enclosing = new EnclosingClass();

    // Some kind of button click event handler
    public void onButtonClicked() {
        this.enclosing.startDoingSomething();
    }
}

私有字段
anonymous
只能存储
AnonymousClassBase
的一个实例,因此第二次调用
startdoongsomething()
将导致封闭类丢失第一个实例的引用。此时,第一个实例是否符合垃圾收集的条件?

只是为了更新我的发现,以便其他人能够从中受益。为了进一步说明这一点,我进一步修改了代码:

public class EnclosingClass {
    private AnonymousClassBase anonymous;
    private Object enclosingClassField = new Object();

    public void startDoingSomething() {
        this.anonymous = new AnonymousClassBase() {
            // Takes some significant load on memory for each anonymous object
            private double[] memoryLoad = new double[9999999];

            // Just taking reference of something belonging to enclosing class
            private Object test = EnclosingClass.this.enclosingClassField;

            @Override public void anonymouslyDoSomething() {
                EnclosingClass.this.doSomething("Did something anonymously!");
            }
        };

        this.anonymous.anonymouslyDoSomething();
    }

    private void doSomething(final String something) {
        System.out.println(something);
    }
}

public abstract class AnonymousClassBase {
    public abstract void anonymouslyDoSomething();
}

public class MainClass {
    private final EnclosingClass enclosing = new EnclosingClass();

    // Some kind of button click event handler
    public void onButtonClicked() {
        this.enclosing.startDoingSomething();
    }
}
主要区别在于匿名对象的内存负载几乎为76.3MB。JVM慢慢增加到大约2.9GB,下降到大约300MB,这表明确实发生了垃圾收集来删除这些匿名类对象


因此,我的结论是,匿名类对象可以包含属于其封闭类对象的任何对象的引用。当匿名类对象持有某个甚至其封闭类对象都不再持有的引用时,它也将丢失该引用。在某种意义上,匿名类对象持有其封闭类对象的弱引用,属于封闭类对象的任何对象引用都是从封闭类派生的(例如,示例中的
封闭类字段
对象).

只是为了更新我的发现,以便其他人能够从中受益。为了进一步说明这一点,我进一步修改了代码:

public class EnclosingClass {
    private AnonymousClassBase anonymous;
    private Object enclosingClassField = new Object();

    public void startDoingSomething() {
        this.anonymous = new AnonymousClassBase() {
            // Takes some significant load on memory for each anonymous object
            private double[] memoryLoad = new double[9999999];

            // Just taking reference of something belonging to enclosing class
            private Object test = EnclosingClass.this.enclosingClassField;

            @Override public void anonymouslyDoSomething() {
                EnclosingClass.this.doSomething("Did something anonymously!");
            }
        };

        this.anonymous.anonymouslyDoSomething();
    }

    private void doSomething(final String something) {
        System.out.println(something);
    }
}

public abstract class AnonymousClassBase {
    public abstract void anonymouslyDoSomething();
}

public class MainClass {
    private final EnclosingClass enclosing = new EnclosingClass();

    // Some kind of button click event handler
    public void onButtonClicked() {
        this.enclosing.startDoingSomething();
    }
}
主要区别在于匿名对象的内存负载几乎为76.3MB。JVM慢慢增加到大约2.9GB,下降到大约300MB,这表明确实发生了垃圾收集来删除这些匿名类对象


因此,我的结论是,匿名类对象可以包含属于其封闭类对象的任何对象的引用。当匿名类对象持有某个甚至其封闭类对象都不再持有的引用时,它也将丢失该引用。在某种意义上,匿名类对象持有其封闭类对象的弱引用,属于封闭类对象的任何对象引用都是从封闭类派生的(例如,示例中的
enclosingClassField
对象)。

当您与匿名类共享类变量时,会发生内存泄漏(使用后不要将其取消设置)嗯,我在匿名类中添加了
private double[]memoryLoad=new double[999999];
,我的机器上的JVM似乎在内存消耗达到2.9GB后对其进行了垃圾收集。因此,我似乎回答了我自己的问题……格式良好的问题已经是答案的一半:)内存泄漏发生在您与anonymous共享您的类变量时(使用后不要在那里取消设置它们)嗯,我添加了
private double[]memoryLoad=new double[999999]
进入匿名类,我的机器上的JVM似乎在内存消耗达到2.9GB后对其进行了垃圾收集。所以我似乎回答了我自己的问题……格式良好的问题已经是答案的一半:)