Thanks — that is useful and I've shared it with my team. I finally got around to setting up cycle_finder and plugged a few leaks as a result.Meanwhile, I'm finding many memory leaks (using Instruments) that appear to be related to Gson deserialization. Most of this work happens in the background via android.os.AsyncTask. I see that jre_emul's cycle_whitelist.txt contains these:FIELD android.os.AsyncTask.mFutureFIELD android.os.AsyncTask.mWorkerBut these fields are initialized as anonymous classes whose methods refer to the parent AsyncTask, and as far as I can tell they are never nulled-out. Wouldn't this lead to a leak with every AsyncTask? I'm wondering if maybe the Gson-related leaks are actually a result of this.
In general, does this mean anonymous classes are almost always off-limits for code that will be translated?
On Monday, January 30, 2017 at 4:18:01 PM UTC-5, Lukhnos Liu wrote:We've made a blog post about breaking retain cycles in your cross-platform code:In addition to J2ObjC's @Weak and @WeakOuter annotations, it also covers lambdas as well as a few tools and techniques that we find helpful.
--
You received this message because you are subscribed to the Google Groups "j2objc-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to j2objc-discus...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
On Tue, 31 Jan 2017 at 17:41 Daniel Dickison <danield...@gmail.com> wrote:Thanks — that is useful and I've shared it with my team. I finally got around to setting up cycle_finder and plugged a few leaks as a result.Meanwhile, I'm finding many memory leaks (using Instruments) that appear to be related to Gson deserialization. Most of this work happens in the background via android.os.AsyncTask. I see that jre_emul's cycle_whitelist.txt contains these:FIELD android.os.AsyncTask.mFutureFIELD android.os.AsyncTask.mWorkerBut these fields are initialized as anonymous classes whose methods refer to the parent AsyncTask, and as far as I can tell they are never nulled-out. Wouldn't this lead to a leak with every AsyncTask? I'm wondering if maybe the Gson-related leaks are actually a result of this.You're right about AsyncTask, these do look like reference cycles. It looks as though these fields were whitelisted when AsyncTask was added without giving them a closer look. I think they could use @RetainedWith annotations, unless it can be proven that these children can't outlive the AsyncTask parent, then @WeakOuter can be used. I'll work on a fix for this. In the meantime you can try adding @RetainedWith to both fields. Let me know if that fixes the leaks.
In general, does this mean anonymous classes are almost always off-limits for code that will be translated?Not necessarily. Anonymous classes and lambdas are still very useful and don't always cause cycles. The more specific pattern to be wary of is when an anonymous class (or lambda or non-static inner) is assigned to a field in its parent class. In this situation, if the child reference is never held by anything but its parent, then a @WeakOuter can easily be applied without any other change.
--