I wrote that debugging code because of a couple of memory leaks I
found in the Android codebase. Like you said, a Message has a
reference to the Handler which, when it's inner and non-static, has a
reference to the outer this (an Activity for instance.) If the Message
lives in the queue for a long time, which happens fairly easily when
posting a delayed message for instance, you keep a reference to the
Activity and "leak" all the views and resources. It gets even worse
when you obtain a Message and don't post it right away but keep it
somewhere (for instance in a static structure) for later use.

If you want to use the equivalent of an inner-class but not risk a
leak, here's a simple pattern:

class OuterClass {
  class InnerClass {
    private final WeakReference<OuterClass> mTarget;

    InnerClass(OuterClass target) {
      mTarget = new WeakReference<OuterClass>(target);
    }

    void doSomething() {
      OuterClass target = mTarget.get();
      if (target != null) target.do();
    }
  }
}

On Sat, Apr 4, 2009 at 12:15 AM, Greg Krimer <gkri...@gmail.com> wrote:
>
> Thank you very much for the reply! After reading what Fadden said
> weeks ago, I happily converted my static inner handler classes to non-
> static ones.
>
> Just recently, I was browsing the source code of Handler and came
> across this bit of internal Android debugging:
>
>    /*
>     * Set this flag to true to detect anonymous, local or member
> classes
>     * that extend this Handler class and that are not static. These
> kind
>     * of classes can potentially create leaks.
>     */
>    private static final boolean FIND_POTENTIAL_LEAKS = false;
>
> There is some code further down that uses reflection to locate such
> subclasses if this flag is true.
>
> My handlers fall into the category of non-static member classes, so I
> am curious how such classes could cause a memory leak. My initial
> thinking was that handlers could perhaps accumulate in a collection
> associated with the MessageQueue. But handlers are never placed into
> collections, as far as I can tell. The reference to the handler is in
> the message. Clever! (And in any case if the memory leak is due to an
> ever-growing collection of handlers somewhere then that has nothing to
> do with whether or not the handler class is static or not.)
>
> Just wondering if someone can shed some light on this comment in the
> Android source code.
>
> Thanks,
>
> Greg
>
> On Mar 10, 4:08 pm, fadden <fad...@android.com> wrote:
>> On Mar 9, 7:17 pm, Greg Krimer <gkri...@gmail.com> wrote:
>>
>> > I have been finding it convenient to extend Handler in many of my
>> > activities to handle messages specific to the activity. The handler
>> > sublass is an inner class of the activity and needs to access its
>> > state. I am wondering if there is any performance difference between
>> > making the handler subclassstaticand passing in the activity
>> > explicitly in its constructor or making the subclass an "instance
>> > class" and letting the vm worry about my accessing members of the
>> > containing activity.
>>
>> There's no real difference between explicitly and implicitly passing
>> the outer-class reference around.  Your example above is essentially
>> doing what javac does automatically.
>>
>> Staticinner classes have some useful properties, e.g. you know
>> they're not modifying state in the parent, and you can use
>> Class.newInstance() with them.  There's no performance magic though.
>>
>> If you're really curious, write it both ways in trivial source files,
>> compile them, then view them with "javap -private -verbose <Class>" or
>> "dx --dump <Class.class>".  They should look about the same.
> >
>



-- 
Romain Guy
Android framework engineer
romain...@android.com

Note: please don't send private questions to me, as I don't have time
to provide private support.  All such questions should be posted on
public forums, where I and others can see and answer them

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers-unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to