For a simple demonstration of how BitmapFactory leaks, try this:

{
   new Timer().schedule(timerTask, 10, 10);
}

TimerTask timerTask = new TimerTask() {
   String filePath = [point this to a valid JPG file];
   public void run() {
       System.gc();
       BitmapFactory.decodeFile(filePath);
       System.gc();
   };

You will leak >16KB with every iteration. If you go into the
BitmapFactory code itself (in decodeStream) and explicitly call close
() on the BufferedInputStream it creates, it will not leak.
(Obviously, you may only close it if decodeStream actually creates a
BufferedInputStream). So somehow the JDWP must be holding on to
something, and it must be weak enough to have a close() call (which
essentially just sets the reference to null) take care of it. [Note
that this is not a proper fix, this was discussed at length in change
6418.]

I know that this is a nasty thing to deal with, at the same time this
is effectively preventing me from debugging some of my apps for a
prolonged period.

-Mike


On Jan 6, 2:18 pm, fadden <[email protected]> wrote:
> On Jan 5, 1:59 pm, EboMike <[email protected]> wrote:
>
> > This problem seems to be particularly prevalent with exceptions - I
> > wrote a test app that throws an exception every 10ms and it OOMs very
> > quickly (and you can see the memory pile up), but also with files
> > (which was what 6418 was about in the first place -- I called close()
> > on a BufferedInputStream, and that kind of closed a big leak when
> > using the debugger).
>
> Exceptions could be handled better in the VM, though it's a little
> awkward to do so.  The code is structured such that the JDWP support
> is isolated from the bulk of the VM; only dalvik/vm/Debugger.c talks
> to both sides.  As a result, we end up adding the exception to the
> "seen objects" list before passing it into the "is this exception
> interesting" function, so we hold on to it even if the exception isn't
> actually passed up to the debugger.
>
> There's no trivial fix for this, though pre-flighting might do the
> trick.  I'd prefer to fix it more generally, treating the debugger
> "seen" list as weak references, but that's more work.
>
> Of course, the flip side of this is that apps shouldn't be throwing so
> many exceptions that it has a noticeable effect on memory usage.  Not
> always avoidable, of course.
>
> I'm not sure what the issue with the BufferedInputStream would be.
> They (like graphics) may have memory usage tied to a finalizer, which
> means you need to gc-finalize-gc before memory is actually released.
> The finalizer thread does run even when the app is being debugged, so
> that shouldn't cause a problem in and of itself.  It *is* possible to
> OOM when memory is pending finalization, which might explain why you
> avoided an OOM with an explicit System.gc() call.  The GC does not
> currently wait for the finalizer thread, which at best it could do for
> a limited time period (you have to be careful since the finalizer
> thread could be waiting on a lock held by the thread doing the GC).
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to