参考到最终对象匿名类的构造函数泄漏? [英] Reference to final object in anonymous class constructor a leak?

查看:112
本文介绍了参考到最终对象匿名类的构造函数泄漏?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我传递一个可运行到服务。可运行的持续时间可能活得比片段/活动传递它。我想知道如果下面的code段将维持在可运行内部参考泄漏FRAG对象吗?我知道我可以移动含断枝整个线外可运行的(比如我用串键=断枝......所做的那样),但我要求只是为了得到如何/时,一个匿名类会泄漏的理解对象。

我真的不能确定。可运行只需要断枝在初始化实例来判断一个变量,它的在线这里初始化。因此在理论上,它并不需要在创建在线实例后不得不断枝任何参考。

如果我有一个参考的run()函数来FRAG,我想泄漏然后将得到保障,因为它需要保持的frag活在未来的某个时候引用它(和片段很可能是GC ð在这一点,但对于参考)。

 私有静态无效fg_downloadFile(最终FragMyDrive FRAG,最终文件文件,最终驱动器驱动器){    最终字符串键= frag.getCastedActivity()getKey()。    可运行rx_downloadFile =新的Runnable(){        上下文ServiceContext = frag.getCastedActivity()MSERVICE。        @覆盖
        公共无效的run(){            bg_downloadFile(ServiceContext,钥匙,文件,驱动器);
        }
    };    // ....提交可运行的服务...
}


解决方案

正如你可能知道,你必须变量的最后的声明之外,但他们在一个匿名类使用它们的时候。这里的Java的窍门是的复制的所有这些变量到该匿名类的隐式生成实例字段。

话虽如此,这意味着确实有抱着外部范围的所有访问的变量的副本实例字段(在你的可运行)。在你的榜样,这也将有一个参考的 FragMyDrive 因为你只是访问它。

所有这些对象成为在同一时间您可运行的符合垃圾收集符合垃圾收集。这意味着引用您的 FragMyDrive 内您可运行保持该对象,只要它运行的是活着。

它总是缩小到你真正需要这些引用一个好主意:

 私有静态无效fg_downloadFile(最终FragMyDrive FRAG,最终文件文件,最终驱动器驱动器){
    最终字符串键= frag.getCastedActivity()getKey()。
    最后上下文的背景下= frag.getCastedActivity()MSERVICE。    可运行rx_downloadFile =新的Runnable(){
        @覆盖
        公共无效的run(){
            bg_downloadFile(背景下,钥匙,文件,驱动器);
        }
    };
    // ....提交可运行的服务...
}

下面唯一的(隐式生成)实例字段是:

 字符串键
上下文的背景下
文件fil​​e
驱动器驱动器

I'm passing a runnable to a service. The runnable duration may outlive the fragment / activity that passes it. I'm wondering if the following code snippet would leak the frag object by maintaining a reference inside the runnable? I realize I can move the whole line containing frag outside of the runnable (like I did with "String key = frag..."), but I'm asking simply to get an understanding of how/when an anonymous class would leak an object.

I'm really not certain. The runnable only needs frag to determine a variable upon initializing the instance, and it's initialized in-line here. So in theory, it doesn't need to have any reference to frag after creating the in-line instance.

If I had a reference to frag in the run() function, I would think a leak then would be guaranteed as it would need to keep frag alive to reference it sometime in the future (and frag might very well be gc'd at that point, but for the reference).

private static void fg_downloadFile(final FragMyDrive frag, final File file, final Drive drive){

    final String key = frag.getCastedActivity().getKey();

    Runnable rx_downloadFile = new Runnable() {

        Context ServiceContext = frag.getCastedActivity().mService;

        @Override
        public void run() {

            bg_downloadFile(ServiceContext, key, file, drive);
        }
    }; 

    //.... Submit runnable to service...
}

解决方案

As you might know, you must make variables final when declaring them outside but using them in an anonymous class. The Java trick here is to copy all those variables into implicitly generated instance fields of that anonymous class.

Having said this, it means that there are indeed instance fields (in your runnable) holding copies of all accessed variables of the outer scope. In your example, it would also have a reference to the FragMyDrive as you are simply accessing it.

All those objects become eligible for garbage collection at the same time your runnable becomes eligible for garbage collection. That means the reference to your FragMyDrive inside your runnable keeps that object alive as long as it is running.

It's always a good idea to narrow down those references to what you really need:

private static void fg_downloadFile(final FragMyDrive frag, final File file, final Drive drive){
    final String key = frag.getCastedActivity().getKey();
    final Context context = frag.getCastedActivity().mService;

    Runnable rx_downloadFile = new Runnable() {
        @Override
        public void run() {
            bg_downloadFile(context, key, file, drive);
        }
    }; 
    //.... Submit runnable to service...
}

Here the only (implicitly generated) instance fields are:

String key
Context context
File file
Drive drive

这篇关于参考到最终对象匿名类的构造函数泄漏?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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