Reference to final object in anonymous class constructor a leak?

旧街凉风 提交于 2019-12-04 19:27:47

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

I'm not sure I understand your use of the word inline correctly but in any case, I don't think anything is leaked here.

Var final String key is simply a local reference in your static function fg_downloadFile() so it's freed when going out of scope at the end of the function.

The Runnable anonymous inner class may still hold a reference (again, not to frag but to some sub-property therein) for as long as the Runnable thread lives. (More precisely, the compiler actually generates an implementation of Runnable with a constructor and final member variables that copy any implicitly used references to whatever is available in fg_downloadFile()'s scope.)

But in any case, once the all code has been executed, all references to (sub-members of) frag will be removed and the garbage collector can pick up the trash.

Hope this helps.

Interesting question. Do you have some experience in programming without automatic garbage collection, like Objective C?

But to answer your question, I don't see why it would be a leak. What I suppose will happen is that the Runnable will keep a reference to frag for it's own use, but at some point in the future, frag will get garbage collected as well once the service does not need it anymore, and hence it's not refering to it.

As garbage collection works, once an object is no longer referenced, it will be subject to garbage collection and deallocated.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!