[Java]接口和内存泄漏

时间:2015-10-02 12:43:50

标签: java memory-leaks interface

我对接口和内存泄漏有疑问,考虑到下面的代码块,是否会导致内存泄漏? 如果是,那么最佳解决方案或替代方案是什么?

select row_number() over () num
   from my_big_table 
   fetch first X rows only

我知道我可以将变量public class MyClass { public interface MyClassListener{ doStuff(); } public doSomething(){} } public class OtherClass { private List<MyClass> list = new ArrayList<MyClass>(); private boolean doingStuff = false; public void setListener(MyClassListener list) { //Sets the listener} public MyClass.MyClassListener listener = new MyClass.MyClassListener() { public void doStuff(){ doingStuff = true; } } public void addMyClass(MyClass obj) { obj.setListener(listener); list.add(obj); } public void doSomethingInMyClass(int index) { ....update some stuff.... list.get(index).doSomething(); } } 声明为listener,因此它不会引用static并将该引用分配给OtherClass但是我要去内存泄漏无论如何? 由于引用将保存对包含包含我的对象的列表的对象的引用。它就像一条链子。

更新

我更新了我的问题,因为您可以看到WeakReference有一个名为MyClass的方法,而doSomething()有一个名为OtherClass的方法调用doSomethingInMyClass方法但更新一些参数。 我想要的是避免使用doSomething并获得有关更改的通知。

1 个答案:

答案 0 :(得分:0)

以下是您的情况示例:

interface I { }

class A {
    List<I> list = new ArrayList<>();
    void add(I item) { list.add(item); }
}

class B {
    A other;
    void setA(A a) {
        final B self = this;
        a.add(new I() { B owner = self; });
        other = a;
    }
}

[...]

public static void main (String[] args)
{                   // 1
    A a = new A();  // 2
    B b = new B();  // 3
    b.setA(a);      // 4
}                   // 5

main范围的开头,(1)中的引用集为空。 ab设置为在(4)中相互引用。然后在(5)中的范围末尾删除对ab的引用。结果是一个自我引用对象的岛屿。

您可以按如下方式显示(非null)引用的集合:

  1. {}
  2. {a, a.list}
  3. {a, a.list, b}
  4. {a, a.list, a.list[0], a.list[0].owner, b, b.other}
  5. {a.list, a.list[0], a.list[0].owner, b.other}
  6. 最后,您引用了a中的列表,它包含对I中内部B的一个或多个引用,其中包含对其所有者{{1}的引用},包含对b的引用。当垃圾收集器从该列表中添加每个对象的引用计数时,如果这些计数等于实际引用计数(即列表完全是自引用的),它可以将它们全部删除。