带有活动和适配器的循环内存引用,Presenter

时间:2016-02-20 13:47:02

标签: android memory-leaks garbage-collection heap-memory

如果我有A级和B级。那么A的B对象如下所示,B参考A。

class A extends Activity{
    private B objectB;
    public A(){
        objectB= new B(this);
    }
}

class B{
    private A objectA;
    public B(A a){
        objectA= a;
    }
}

当一个类被销毁时,它的变量objectB也应该被销毁。那么objectA会发生什么?它是否仍然引用A偶objectB被销毁?或者A不会被垃圾收集即使它被销毁,因为objectA持有它的引用?在this issue上,发生了类似的情况并将其视为内存泄漏。

2 个答案:

答案 0 :(得分:1)

这取决于A和B中的对象引用是否是彼此相同的对象引用。在编辑示例以包括A和B如何实例化(newed up)之后,示例中没有内存泄漏,因为每个实例创建的实例不是相同的实例(不同的内存引用)。

在这种情况下可能会创建内存泄漏,具体取决于构造或实例化两个类的方式。上面给出的类的定义没有足够的信息来确定是否存在内存泄漏。

例如,给定以下类定义:

    class A extends Activity{
        private B objectB;

        public void setB(B b){
            objectB = b;
        }
    }

    class B{
        private A objectA;

        public B(A a){
            objectA = a;
        }
    }

如果您随后创建了一个实例化A和B的Test类,如下所示:

    class Test(){
        public static void main(String... args){
            A a = new A();
            B b = new B(a);
            a.setB(b);
        }
    }

在这种情况下,引入了内存泄漏,因为在实例化B时,它会传递给A的引用,然后我们将A中的B显式设置为持有对此A实例的引用的相同B.

如果我们将Test中的代码更改为一行:

    class Test(){
        public static void main(String... args){
            A a = new A();
            B b = new B(a);
            a.setB(new B()); //Modified this line
        }
    }

现在我们不再有内存泄漏,因为我们传递给A的B与持有A的引用的B不是同一个实例。

答案 1 :(得分:1)

在上面的示例代码中,AB类之间存在循环引用。这些will be garbage collected如果Application中的任何其他对象实例无法访问它们。

&#34; Activity被销毁&#34;并不意味着它是垃圾收集。但是当Activity被垃圾收集时,它的变量Views(仅Activity引用)也将被垃圾收集。 我认为,在onDestroy()类的Activity上,变量将被分配给null,但它们的值仍将保留在内存中,直到它们被垃圾回收。< / p>

在有问题的链接中,Presenter对象引用了Activity,反之亦然。如果它们未被Application中的其他对象实例引用,则它们将被垃圾收集。但是Activityreferenced by Presenter,它由Subscription对象引用,它也被某些静态类引用。

同样的规则适用于创建Adapter并从Context传递Activity时。如果它们都没有被其他对象引用,则不会发生泄漏。但要谨慎,you should pass Application Context改为Adapter而不是Activity Context