I take that back... I looked a lot more into the issue, and it seems
that the leak only occurs when a debugger is attached.

Here is something to try when you're plagued by OOMs -- run your app
directly through the emulator without a debugger attached. Is the
memory situation any better?

I notice that I'm leaking lots of memory, even when doing something as
primitive as throwing an exception. Without a debugger attached,
things seem stable. Not that this means that all my memory woes are
solved, but I've just made this discovery and will now need to re-
evaluate all OOM problems I had.

-Mike


On Dec 31 2008, 10:39 am, EboMike <ebom...@gmail.com> wrote:
> There is clearly something wrong. I've tried to plug a leak in
> BitmapFactory.decodeStream() (which is called internally by
> BitmapFactory.decodeFile() ), and that indeed fixed a memory leak
> whenever you create a bitmap (seehttp://review.source.android.com/6418),
> but after Romain reviewed it, I realized that the problem is possibly
> much deeper in the gc itself.
>
> BitmapFactory.decodeStream() sometimes creates a BufferedInputStream()
> and doesn't close it.... but in theory, that shouldn't cause a memory
> leak. The GC should realize that nobody references the
> BufferedInputStream(), collect it, and thereby realize that nobody
> holds its enclosing stream and collect that too. Except that this
> doesn't happen. (Unless I missed something secret that links the
> FilteredInputStream to the other stream on a lower level.)
>
> I've made a simple test app that creates a Bitmap using
> BitmapFactory.decodeFile() every 10ms. It doesn't even store the
> return value, and lo and behold, the app runs out of memory unless I
> modify the Android OS to close the BufferedInputStream.
>
> I'll take a peek at the mark and sweep mechanism itself, but it would
> be more productive if somebody at Android could do that since they're
> a lot more familiar with all this.
>
> Btw, Jose - I too got OOMs when I was nowhere close to 16MB, although
> my suspicion is that the JNI memory usage is not easily accessible in
> the DDMS (even though somebody said it is supposedly taken from the
> app's heap as well).
>
> -Mike
>
> On Dec 31, 5:35 am, qvark <joseluishuertasfernan...@gmail.com> wrote:
>
> > We have also been noticing this kind of behaviour in our application.
>
> > What is worse, many of the OOM problems (but not all) have been solved
> > using explicits System.gc() calls before the operation that caused the
> > OOM. IMHO this means we were doing our homework releasing all the
> > references to unused objects, but Dalvik was not freeing the memory
> > until we have 'forced' it.
>
> > This morning have been the last example: take a picture with the
> > camera and display it in a new activity, finish that activity and when
> > you try to capture a new picture you will get an OOM. You could thing
> > we are doing something wrong and there is some reference to the image
> > that prevents it from being garbage collected, but then I modify the
> > activity that takes the pictures and put a System.gc(); before the
> > takePicture() call and... it works! now you can take a picture,
> > visualize it, go back and take another picture as many times as you
> > want.
>
> > I have always considered an explicit call to System.gc() a bad
> > practice because that should be the VM's work not the programmer one,
> > so I was very puzzled when I tried this and it worked... is this the
> > intended behaviour in Dalvik? should we populate our code with
> > System.gc() calls?
>
> > BTW, Romain, please believe us when we say there are OOM exceptions
> > when you are not even close to the theoretical 16 MB limit and you try
> > to reserve a significant amount of memory (say 1 MB for example).
>
> > Thanks,
>
> > Jose Luis.
>
> > On Dec 30, 6:42 pm, blindfold <seeingwithso...@gmail.com> wrote:
>
> > > I wonder if there could be some bug in this intended VM-like
> > > behaviour, because my app continuously uses about 3 to 4 MB on the dev
> > > phone 1 according to DDMS (with similar figures reported by freeMemory
> > > ()), and DDMS reports a heap size of about 6 MB (not a typo, not 16
> > > MB). And yet my app occasionally crashes due to an OutOfMemoryError
> > > exception when its peak usage gets close to that fixed 6 MB (not 16
> > > MB), either in my own (modest, few hundred KB) memory allocations -
> > > for which I can add try-catch blocks as a crude workaround to keep the
> > > app alive, or due an out-of-memory error in the low-level camera
> > > preview code, which then inevitably causes a crash. Never do I see the
> > > heap (in DDMS) gradually climb up from 6 MB towards 16 MB. Basically
> > > it looks like the heap does not always grow even when memory
> > > allocations require it? Or has the system already reserved 10 MB of
> > > the 16 MB for things that I am not aware of such that the reported
> > > heap cannot grow above 6 MB?
>
> > > Thanks
>
> > > On Dec 4, 9:36 am, Romain Guy <romain...@google.com> wrote:
>
> > > > The heap works pretty much like in a regular VM. As your app needs
> > > > more memory the heap grows accordingly (but doesn't shrink.) For
> > > > instance, if you are using 1 MB out of your 2 MB of allocated heap and
> > > > need to load 2 more MB, the heap will grow to more than 3 MB, and you
> > > > will use 3 MB out of the heap. But when the heap reaches a total
> > > > allocated size of 16 MB and your app needs more memory, you get an
> > > > OutOfMemoryError.
>
> > > > On Wed, Dec 3, 2008 at 11:30 PM, EboMike <ebom...@gmail.com> wrote:
>
> > > > > Thanks, Romain. I'm grabbing them from a server, but you're right, if
> > > > > anything, I should convert and re-save them in a smaller format before
> > > > > caching them locally. Well, I just tried to get it running quickly :)
>
> > > > > One laaast thing - You mentioned that an app has a 16MB heap. How is
> > > > > that split up? A Runtime.getRuntime().freeMemory() right on startup in
> > > > > the app above gives me about 800KB or so (although the app is later
> > > > > able to allocate 1MB to decode an image). I'm not very familiar with
> > > > > Dalvik's memory management, how is the whole thing set up?
>
> > > > > -Mike
>
> > > > > On Dec 3, 11:26 pm, Romain Guy <romain...@google.com> wrote:
> > > > >> Well you could start by not loading such huge images in a Gallery.
> > > > >> Even if the recycler was working correctly it is a LOT of data to 
> > > > >> read
> > > > >> and to decode. It's also a lot of wasted memory (and it also slows
> > > > >> drawing down since the bitmaps are drawn rescaled.) You should use
> > > > >> BitmapFactory.Options or Bitmap.createScaledBitmap to load your image
> > > > >> pre-scaled to a much more reasonable size.
>
> > > > >> On Wed, Dec 3, 2008 at 11:23 PM, EboMike <ebom...@gmail.com> wrote:
>
> > > > >> > Thanks a lot for the very quick replies. One last thing: Do you 
> > > > >> > happen
> > > > >> > to have any remote idea about when the next SDK release is 
> > > > >> > scheduled?
> > > > >> > My app is currently running out of memory a lot :)
>
> > > > >> > On Dec 3, 11:13 pm, Romain Guy <romain...@google.com> wrote:
> > > > >> >> A memory leak is actually totally expected in that case. Gallery, 
> > > > >> >> like
> > > > >> >> ListView, GridView, etc. uses a recycling heap. Every time a view 
> > > > >> >> is
> > > > >> >> unused, it is moved to the recycler. Unfortunately, if it's never
> > > > >> >> taken out of the recycler...
>
> > > > >> >> On Wed, Dec 3, 2008 at 11:07 PM, EboMike <ebom...@gmail.com> 
> > > > >> >> wrote:
>
> > > > >> >> > Thanks a lot, Romain! Question though - even if the gallery is 
> > > > >> >> > not
> > > > >> >> > converting the views, why doesn't it release references to them 
> > > > >> >> > as you
> > > > >> >> > move away?
>
> > > > >> >> > Say, I move from view 0 to view 1, with view 0 being completely 
> > > > >> >> > off-
> > > > >> >> > screen, the gallery should remove its reference to view 0 since 
> > > > >> >> > it is
> > > > >> >> > no longer needed, and thus allow the gc to free up any memory it
> > > > >> >> > holds. In fact, when I go back to view 0, I can see that a new 
> > > > >> >> > view is
> > > > >> >> > created. So what happened to the old view 0? Even with view 
> > > > >> >> > conversion
> > > > >> >> > not working, there shouldn't be memory leaks.
>
> > > > >> >> > -Mike
>
> > > > >> >> > On Dec 3, 11:04 pm, Romain Guy <romain...@google.com> wrote:
> > > > >> >> >> I just checked and the bug is simply that Gallery does not 
> > > > >> >> >> convert the
> > > > >> >> >> views. I'll try to fix it as soon as possible.
>
> > > > >> >> >> On Wed, Dec 3, 2008 at 10:45 PM, EboMike <ebom...@gmail.com> 
> > > > >> >> >> wrote:
>
> > > > >> >> >> > I've already asked this in <a 
> > > > >> >> >> > href="http://groups.google.com/group/
> > > > >> >> >> > android-developers/msg/9cdbf47be2505810?hl=en">This 
> > > > >> >> >> > thread</a>: Here
> > > > >> >> >> > is a pretty simple Gallery setup. It seems to leak with 
> > > > >> >> >> > every image
> > > > >> >> >> > that's loaded (see the original thread for details).
>
> > > > >> >> >> > I'm tempted to file it as a bug, but I want to mention it 
> > > > >> >> >> > here first
> > > > >> >> >> > to make sure I'm not just making a simple mistake in my 
> > > > >> >> >> > usage of the
> > > > >> >> >> > Gallery. Also (as mentioned in another thread), convertView 
> > > > >> >> >> > is always
> > > > >> >> >> > null -- the Gallery never seems to recycle any views. Why?
>
> > > > >> >> >> > To make this run, you will need to put a JPG file into the 
> > > > >> >> >> > data folder
> > > > >> >> >> > (see code).
>
> > > > >> >> >> > package ebomike.memorytest;
>
> > > > >> >> >> > import android.app.Activity;
> > > > >> >> >> > import android.content.Context;
> > > > >> >> >> > import android.graphics.Bitmap;
> > > > >> >> >> > import android.graphics.BitmapFactory;
> > > > >> >> >> > import android.graphics.drawable.BitmapDrawable;
> > > > >> >> >> > import android.os.Bundle;
> > > > >> >> >> > import android.util.Log;
> > > > >> >> >> > import android.view.View;
> > > > >> >> >> > import android.view.ViewGroup;
> > > > >> >> >> > import android.widget.BaseAdapter;
> > > > >> >> >> > import android.widget.Gallery;
> > > > >> >> >> > import android.widget.ImageView;
>
> > > > >> >> >> > public class MemoryTest extends Activity {
>
> > > > >> >> >> >        Gallery g;
>
> > > > >> >> >> >    /** Called when the activity is first created. */
> > > > >> >> >> >   �...@override
> > > > >> >> >> >    public void onCreate(Bundle savedInstanceState) {
>
> > > > >> >> >> >                String filePath;
>
> > > > >> >> >> >                // NOTE: Make this point to a JPEG file.
> > > > >> >> >> >                filePath = getFilesDir().getPath();
> > > > >> >> >> >                filePath += "/TEST_IMAGE.jpg";
>
> > > > >> >> >> >        super.onCreate(savedInstanceState);
> > > > >> >> >> >        setContentView(R.layout.main);
>
> ...
>
> read more »
--~--~---------~--~----~------------~-------~--~----~
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