How to solve outofmemory error during listview scrolling?
<blockquote>
  <p><strong>Possible Duplicate:</strong><br>
  <a href="http://stackoverflow.com/questions/5082703/android-out-of-memory-error-with-lazy-load-images">Android Out of Memory error with Lazy Load images</a><br>
  <a href="http://stackoverflow.com/questions/13376899/outofmemory-error-during-scrolling-the-listview-fastly">Outofmemory error during scrolling the listview fastly</a>  </p>
</blockquote>



<p>I am using listview to display the images,names from the facebook api.I can able to display images correctly.My problem is when I scroll the list fastly I am getting </p>

<pre><code>    11-15 18:41:29.841: E/dalvikvm-heap(32303): 786432-byte external allocation too large for this process.
11-15 18:41:29.887: I/dalvikvm-heap(32303): Clamp target GC heap from 32.095MB to 32.000MB
11-15 18:41:29.887: E/GraphicsJNI(32303): VM won't let us allocate 786432 bytes
11-15 18:41:29.887: D/dalvikvm(32303): GC_FOR_MALLOC freed 0K, 51% free 4380K/8903K, external 23826K/25864K, paused 31ms
11-15 18:41:29.887: D/skia(32303): --- decoder-&gt;decode returned false
11-15 18:41:29.887: W/dalvikvm(32303): threadid=18: thread exiting with uncaught exception (group=0x40018560)
11-15 18:41:29.887: E/AndroidRuntime(32303): FATAL EXCEPTION: Thread-29
11-15 18:41:29.887: E/AndroidRuntime(32303): java.lang.OutOfMemoryError: bitmap size exceeds VM budget
11-15 18:41:29.887: E/AndroidRuntime(32303):    at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
11-15 18:41:29.887: E/AndroidRuntime(32303):    at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:470)
11-15 18:41:29.887: E/AndroidRuntime(32303):    at com.beerbro.utils.ImageLoader.decodeFile(ImageLoader.java:156)
11-15 18:41:29.887: E/AndroidRuntime(32303):    at com.beerbro.utils.ImageLoader.getBitmap(ImageLoader.java:99)
11-15 18:41:29.887: E/AndroidRuntime(32303):    at com.beerbro.utils.ImageLoader$PhotosLoader.run(ImageLoader.java:214)
</code></pre>

<p>But when I scroll this listview slowly I am not getting any errors.</p>

<p>Here is my Adapter class where I called Imageloader class displayImage method to convert my url into bitmap and set it to imageview.</p>

<pre><code>    public class MySimpleArrayAdapter extends ArrayAdapter&lt;String&gt; {
    private Activity context;
    ArrayList&lt;String&gt; namear,msgar,idar,profimage,postimage,commentsnum,objectid,urlString;

  ImageLoader imageLoader;
  Bitmap[] bitdata;


  public MySimpleArrayAdapter(Activity c,int i,ArrayList&lt;String&gt; postpic, ArrayList&lt;String&gt; names,ArrayList&lt;String&gt; msg,ArrayList&lt;String&gt; id,ArrayList&lt;String&gt; proimg,Bitmap[] bit,ArrayList&lt;String&gt; comment,ArrayList&lt;String&gt; objid,ArrayList&lt;String&gt; web) {

      super(c, i, names);
    Log.e("adapter","adap");
    this.context = c;
    this.namear = names;
    this.msgar = msg;
    this.idar = id;
    this.profimage=proimg;
    this.postimage=postpic;
    this.bitdata=bit;
    this.commentsnum=comment;
    this.objectid=objid;
    this.urlString=web;
   this.imageLoader = new ImageLoader(context);
  }


  @Override
  public View getView(final int position, View convertView, ViewGroup parent) {
      View rowView=convertView ;
      LayoutInflater inflator =   getLayoutInflater();
      rowView = inflator.inflate(R.layout.walldata, null);

      TextView name1 = (TextView) rowView.findViewById(R.id.name);
      TextView message1 = (TextView) rowView.findViewById(R.id.msg);
      ImageView profimg= (ImageView) rowView.findViewById(R.id.profile_pic);
      ImageView postimg= (ImageView) rowView.findViewById(R.id.picpost);
  TextView comments = (TextView) rowView.findViewById(R.id.comment);

     Log.e("user",idar.get(position));


    Log.e("adapter","adap");
   name1.setText(namear.get(position));
    if(msgar.get(position)!=""){
    message1.setText(msgar.get(position));

    }
    else
    {
        message1.setVisibility(View.GONE);
    }
    if(!postimage.get(position).equals(""))
    {try{
         imageLoader.DisplayImage(postimage.get(position).replace(" ", "%20"), postimg) ;

    }
    catch(Exception e){
        e.printStackTrace();
    }
    }
    else
    {
        postimg.setVisibility(View.GONE);
    }
    try{
      imageLoader.DisplayImage(profimage.get(position).replace(" ", "%20"), profimg) ;

    }
    catch(Exception e){
       e.printStackTrace();
    }

       comments.setText(commentsnum.get(position)+"\t"+"Comments");
       comments.setOnClickListener(new OnClickListener() {


        public void onClick(View v) {
            Intent myintent=new Intent(Wall.this,Comments.class);
            myintent.putExtra("name", namear.get(position));
            myintent.putExtra("profimg", profimage.get(position));
            myintent.putExtra("message", msgar.get(position));
            myintent.putExtra("postpic", postimage.get(position));
            myintent.putExtra("objectid", objectid.get(position));
            myintent.putExtra("commentsnum",commentsnum.get(position));
            myintent.putExtra("webservice", urlString.get(position));
            startActivity(myintent);

        }
    });

    return rowView;
  }
</code></pre>

<p>Here is my Imageloader class </p>

<pre><code> public class ImageLoader {

    MemoryCache memoryCache=new MemoryCache();
    FileCache fileCache;
    private Map&lt;ImageView, String&gt; imageViews=Collections.synchronizedMap(new WeakHashMap&lt;ImageView, String&gt;());

    public ImageLoader(Context context){

        photoLoaderThread.setPriority(Thread.NORM_PRIORITY-1);

        fileCache=new FileCache(context);
    }

    public void DisplayImage(String url,ImageView imageView)
    {
        imageViews.put(imageView, url);


        Bitmap bitmap=memoryCache.get(url);

        if(bitmap!=null)
        {
            imageView.setBackgroundDrawable(new BitmapDrawable(bitmap));

            System.gc();
        }
        else
        {
            queuePhoto(url, imageView);

        }    
    }

    private Bitmap createScaledBitmap(Bitmap bitmap, int i, int j, int k) {
        return null;
    }

    private void queuePhoto(String url, ImageView imageView)
    {
        //This ImageView may be used for other images before. So there may be some old tasks in the queue. We need to discard them. 
        photosQueue.Clean(imageView);
        PhotoToLoad p=new PhotoToLoad(url, imageView);
        synchronized(photosQueue.photosToLoad){
            photosQueue.photosToLoad.push(p);
            photosQueue.photosToLoad.notifyAll();
        }

        //start thread if it's not started yet
        if(photoLoaderThread.getState()==Thread.State.NEW)
            photoLoaderThread.start();
    }

   public Bitmap getBitmap(String url) 
    {
        File f=fileCache.getFile(url);

        //from SD cache
        Bitmap b = decodeFile(f);
        if(b!=null)
            return b;

        //from web
        try {
            Bitmap bitmap=null;
            URL imageUrl = new URL(url);
            HttpURLConnection conn = (HttpURLConnection)imageUrl.openConnection();
            conn.setConnectTimeout(30000);
            conn.setReadTimeout(30000);
            InputStream is=conn.getInputStream();
            OutputStream os = new FileOutputStream(f);
            Utils.CopyStream(is, os);
            os.close();
            bitmap = decodeFile(f);
            return bitmap;
        } catch (Exception ex){
           ex.printStackTrace();
           return null;
        }
    }//Lalit

    //decodes image and scales it to reduce memory consumption
    private Bitmap decodeFile(File f){
        try {
            //decode image size
            BitmapFactory.Options o = new BitmapFactory.Options();
            o.inJustDecodeBounds = true;
            BitmapFactory.decodeStream(new FileInputStream(f),null,o);


            //Find the correct scale value. It should be the power of 2.

            final int REQUIRED_SIZE=Wall.width;
            final int REQUIRED_SIZE1=Wall.height;

            int width_tmp=o.outWidth, height_tmp=o.outHeight;
            int scale=1;

            while(true){
                if((width_tmp/2&lt;REQUIRED_SIZE)&amp;&amp;(height_tmp/2&lt;REQUIRED_SIZE1))
                    break;
                width_tmp/=2;
                height_tmp/=2;
                scale*=2;
            }

            //decode with inSampleSize
            BitmapFactory.Options o2 = new BitmapFactory.Options();
            o2.inJustDecodeBounds = true;
            BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
            o2.inSampleSize=scale;
            o2.inJustDecodeBounds = false;

            return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);


        } catch (FileNotFoundException e) {}
        return null;
    }

    //Task for the queue
    private class PhotoToLoad
    {
        public String url;
        public ImageView imageView;
        public PhotoToLoad(String u, ImageView i){
            url=u; 
            imageView=i;
        }
    }

    PhotosQueue photosQueue=new PhotosQueue();

    public void stopThread()
    {
        photoLoaderThread.interrupt();
    }

    //stores list of photos to download
    class PhotosQueue
    {
        private Stack&lt;PhotoToLoad&gt; photosToLoad=new Stack&lt;PhotoToLoad&gt;();

        //removes all instances of this ImageView
        public void Clean(ImageView image)
        {
            for(int j=0 ;j&lt;photosToLoad.size();){
                if(photosToLoad.get(j).imageView==image)
                    photosToLoad.remove(j);
                else
                    ++j;
            }
        }
    }

    class PhotosLoader extends Thread {
        public void run() {
            try {
                while(true)
                {
                    //thread waits until there are any images to load in the queue
                    if(photosQueue.photosToLoad.size()==0)
                        synchronized(photosQueue.photosToLoad){
                            photosQueue.photosToLoad.wait();
                        }
                    if(photosQueue.photosToLoad.size()!=0)
                    {
                        PhotoToLoad photoToLoad;
                        synchronized(photosQueue.photosToLoad){
                            photoToLoad=photosQueue.photosToLoad.pop();
                        }
                        Bitmap bmp=getBitmap(photoToLoad.url);
                        memoryCache.put(photoToLoad.url, bmp);
                        String tag=imageViews.get(photoToLoad.imageView);
                        if(tag!=null &amp;&amp; tag.equals(photoToLoad.url)){
                            BitmapDisplayer bd=new BitmapDisplayer(bmp, photoToLoad.imageView);
                            Activity a=(Activity)photoToLoad.imageView.getContext();
                            a.runOnUiThread(bd);
                        }
                    }
                    if(Thread.interrupted())
                        break;
                }
            } catch (InterruptedException e) {
                //allow thread to exit
            }
        }
    }

    PhotosLoader photoLoaderThread=new PhotosLoader();

    //Used to display bitmap in the UI thread
    class BitmapDisplayer implements Runnable
    {
        Bitmap bitmap;
        ImageView imageView;
        public BitmapDisplayer(Bitmap b, ImageView i){bitmap=b;imageView=i;}
        public void run()
        {
            if(bitmap!=null)
                imageView.setBackgroundDrawable(new BitmapDrawable(bitmap));

        }
    }

    public void clearCache() {
        memoryCache.clear();
        fileCache.clear();
    }
    public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, int pixels,int width,int height) {

        Bitmap output = Bitmap.createBitmap(width,height, Config.ARGB_8888);
        Canvas canvas = new Canvas(output);

        final int color = 0xff424242;
        final Paint paint = new Paint();
        final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
        final RectF rectF = new RectF(rect);
        final float roundPx = pixels;

        paint.setAntiAlias(true);
        canvas.drawARGB(0, 0, 0, 0);
        paint.setColor(color);
        canvas.drawRoundRect(rectF, roundPx, roundPx, paint);

        paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
        canvas.drawBitmap(bitmap, rect, rect, paint);

        return output;
    }
</code></pre>

<p>I am scaling the images upto my device screen size i.e 480*854,you can find this in imageloader class,I also mention here for easy understanding</p>

<pre><code>     final int REQUIRED_SIZE=Wall.width;
            final int REQUIRED_SIZE1=Wall.height;

            int width_tmp=o.outWidth, height_tmp=o.outHeight;
            int scale=1;

            while(true){
                if((width_tmp/2&lt;REQUIRED_SIZE)&amp;&amp;(height_tmp/2&lt;REQUIRED_SIZE1))
                    break;
                width_tmp/=2;
                height_tmp/=2;
                scale*=2;
            }
    }
</code></pre>

<p>By looking at the error I can understand that memory is not sufficient for loading bitmap,I dont know how can I deallocate memory at runtime.
 please help me I referred to many of the links in stackoverflow and others but couldnt fix this issue.</p>
