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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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);
>
> >> >> >> >        g = (Gallery) findViewById(R.id.Gallery01);
> >> >> >> >        g.setAdapter(new FullImageAdapter(this, filePath));
> >> >> >> >    }
>
> >> >> >> >    class FullImageAdapter extends BaseAdapter
> >> >> >> >    {
> >> >> >> >        Context context;
> >> >> >> >        String path;
>
> >> >> >> >        FullImageAdapter(Context c, String path)
> >> >> >> >        {
> >> >> >> >                context = c;
> >> >> >> >                this.path = path;
> >> >> >> >        }
>
> >> >> >> >        public int getCount()
> >> >> >> >        {
> >> >> >> >                return 1024;
> >> >> >> >        }
>
> >> >> >> >        public int getViewTypeCount()
> >> >> >> >        {
> >> >> >> >                return 1;
> >> >> >> >        }
>
> >> >> >> >        public boolean hasStableIds()
> >> >> >> >        {
> >> >> >> >                return true;
> >> >> >> >        }
>
> >> >> >> >        public int getItemViewType(int position)
> >> >> >> >        {
> >> >> >> >                return 0;
> >> >> >> >        }
>
> >> >> >> >        public View getView(int position, View convertView, 
> >> >> >> > ViewGroup
> >> >> >> > parent)
> >> >> >> >        {
> >> >> >> >                ImageView view;
>
> >> >> >> >                if (convertView != null)
> >> >> >> >                {
> >> >> >> >                        // Note that we never get here. Why?
> >> >> >> >                        view = (ImageView) convertView;
> >> >> >> >                }
> >> >> >> >                else
> >> >> >> >                {
> >> >> >> >                        view = new ImageView(context);
> >> >> >> >                }
>
> >> >> >> >                Bitmap bitmap = BitmapFactory.decodeFile(path);
> >> >> >> >                BitmapDrawable drawable = new 
> >> >> >> > BitmapDrawable(bitmap);
> >> >> >> >                view.setImageDrawable(drawable);
>
> >> >> >> >                return view;
> >> >> >> >        }
>
> >> >> >> >        public Object getItem(int position)
> >> >> >> >        {
> >> >> >> >                return position;
> >> >> >> >        }
>
> >> >> >> >        public long getItemId(int position)
> >> >> >> >        {
> >> >> >> >                return position;
> >> >> >> >        }
> >> >> >> >    }
> >> >> >> > }
>
> >> >> >> > The layout:
>
> >> >> >> > <?xml version="1.0" encoding="utf-8"?>
> >> >> >> > <LinearLayout xmlns:android="http://schemas.android.com/apk/res/
> >> >> >> > android"
> >> >> >> >    android:orientation="vertical"
> >> >> >> >    android:layout_width="fill_parent"
> >> >> >> > android:layout_height="fill_parent">
> >> >> >> > <TextView
> >> >> >> >    android:layout_width="fill_parent"
> >> >> >> >    android:layout_height="wrap_content"
> >> >> >> >    android:text="@string/hello"
> >> >> >> >    />
> >> >> >> > <Gallery android:id="@+id/Gallery01"
> >> >> >> > android:layout_width="fill_parent"
> >> >> >> > android:layout_height="fill_parent"></Gallery>
>
> >> >> >> > </LinearLayout>
>
> >> >> >> --
> >> >> >> Romain Guywww.curious-creature.org
>
> >> >> --
> >> >> Romain Guywww.curious-creature.org
>
> >> --
> >> Romain Guywww.curious-creature.org
>
> --
> Romain Guywww.curious-creature.org
--~--~---------~--~----~------------~-------~--~----~
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