我对接口和内存泄漏有疑问,考虑到下面的代码块,是否会导致内存泄漏? 如果是,那么最佳解决方案或替代方案是什么?
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
并获得有关更改的通知。
答案 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)中的引用集为空。 a
和b
设置为在(4)中相互引用。然后在(5)中的范围末尾删除对a
和b
的引用。结果是一个自我引用对象的岛屿。
您可以按如下方式显示(非null
)引用的集合:
{}
{a, a.list}
{a, a.list, b}
{a, a.list, a.list[0], a.list[0].owner, b, b.other}
{a.list, a.list[0], a.list[0].owner, b.other}
最后,您引用了a
中的列表,它包含对I
中内部B
的一个或多个引用,其中包含对其所有者{{1}的引用},包含对b
的引用。当垃圾收集器从该列表中添加每个对象的引用计数时,如果这些计数等于实际引用计数(即列表完全是自引用的),它可以将它们全部删除。