活页夹preventing垃圾收集 [英] Binder preventing garbage collection

查看:294
本文介绍了活页夹preventing垃圾收集的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想我找到了内存泄漏,想证实我认为可能真正如何Android的活页夹中实现。在这种情况下,我有一个服务和活动,各自在自己的过程。我创建了一个AIDL,让我通过一个IPC方法传递从活动到服务中的回调对象,然后调用了回调时的服务与所请求的任务完成。

I think I tracked down a memory leak and want to confirm what I think may true about how Android's Binder is implemented. In this case I have a Service and an Activity, each in their own process. I created an AIDL that allows me to pass a Callback object from the Activity to the Service through an ipc method and then have the callback called when the Service is done with the requested task.

在很长一段时间,我在想:如果我通过一个新的回调对象的服务,我不保持一个指向回调对象在我的活动为什么不垃圾回收器只是继续前进,收集回调在我的活动过程?因为似乎没有发生,如何在JVM知道什么时候垃圾收集回调在我的活动。

For a long time I was wondering: if I pass a new Callback object to the Service and I don't keep a pointer to the Callback object in my Activity why doesn't the garbage collector just go ahead and collect the Callback in my Activity process? Since that doesn't seem to happen, how does the JVM know when to garbage collect the Callback in my Activity.

我想答案是,活页夹系统保持一个指向我的回调在活动过程中,直到在服务过程中,相应的回调对象有其finalize()方法调用,然后将消息发送到活动释放指针。 这是正确的?如果不是它是如何工作的?

I think the answer is that the Binder system keeps a pointer to my Callback in the Activity process until the corresponding Callback object in the Service process has its finalize() method called, which then sends a message to the Activity to release the pointer. Is this correct? If not how does it work?

我相信这是它带来了有趣的情况下,如果在回调中的活动所指向的东西很内存密集型它不会被收集,直到回调服务被收集。如果服务不内存不足,可能不收集的回调很长一段时间的回调可能只是在活动建立,直到有在活动一个OutOfMemoryError。

I believe it is and it leads to interesting situation where if the Callback in the Activity is pointing to something very memory intensive it won't be collected until the Callback in the Service is collected. If the Service isn't low on memory it might not collect the Callback for a long time and the Callbacks might just build up in the Activity until there is an OutOfMemoryError in the Activity.

推荐答案

尤里是pretty的多少是正确的。

Yury is pretty much correct.

我的服务启动一个线程持有回调并且当线程与它的工作完成,它调用回调和线头。当回调被调用它可能做的工作一点点在我的活动,然后返回在这一点上我没有在我的活动过程中的指针回调。

My Service starts a thread that holds the callback and when the thread is done with its work it calls the callback and the thread ends. When the callback is called it may do a tiny bit of work in my Activity and then return at which point I don't have pointers in my Activity process to the callback.

然而,在活动回调目标将继续指向Android的粘合剂系统,直到服务对应的回调对象被垃圾回收。

However the callback object in the Activity will continue to be pointed to by Android's binder system until the corresponding callback object in the Service is garbage collected.

如果在活动过程中的回调对象主宰消耗大量的内存,然后我在我的活动过程中浪费的内存没有很好的理由,甚至可以得到一个OutOfMemoryError一些其他对象。 解决方案是在我所谓的回调类创建一个简单的方法 destory()来空出所有回调的领域,并调用该方法时,我用我做的回调。

If the callback object in the Activity process dominates some other objects that consume a lot of memory then I am wasting memory in my Activity process for no good reason and could even get an OutOfMemoryError. The solution is to create a simple method in my callback class called destory() to null out all the callback's fields and to call that method when I am done with the callback.

如果回调类是,你可能要考虑将其更改为一个静态内部类,并通过在父类的构造函数中的非静态内部类,这样你就可以空了出来,以及在 destory()方法。

If the callback class is a non-static inner class you may want to consider changing it to a static inner class and passing in the parent class in the constructor, this way you can null that out as well in the destory() method.

这带来了一个有趣的想法,如果父类中的非静态内部回调类的是一种活动和配置的变化情况(如屏幕旋转)回调后通过粘结剂发送,但它被称为前当时的回调将指向旧的活动对象在执行时!

This brings up an interesting thought, if the parent class of a non-static inner callback class is an Activity and a configuration change happens (such as a screen rotation) after the callback is sent through the binder but before it is called back then the callback will be pointing to an old Activity object when it executes!

更新:我发现里面Binder.java这code,当然它被禁止,但它会一直很好,如果他们提到这样的东西在的Javadoc

Update: I discovered this code inside Binder.java, of course it is disabled but it would have been nice if they mentioned this kind of stuff in the Javadocs.

    if (FIND_POTENTIAL_LEAKS) {
        final Class<? extends Binder> klass = getClass();
        if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
                (klass.getModifiers() & Modifier.STATIC) == 0) {
            Log.w(TAG, "The following Binder class should be static or leaks might occur: " +
                klass.getCanonicalName());
        }
    }

这篇关于活页夹preventing垃圾收集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆