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 -~----------~----~----~----~------~----~------~--~---