You should work on getting a smaller example to demonstrate as this is too
much code to read through.

It may also help you solve the problem yourself.
On Dec 20, 2011 3:21 PM, "shyama" <shyama.asoka...@gmail.com> wrote:

> I realised that when when I made a call to System.gc() right after the
> bitmao..recycle() call the heap space  is getting returned to the VM
> heap. But I have been reading about Garbage collection and it seems
> that calling System.gc() is not a good programming practice. Is there
> another way to make sure that the garbage collection happens right
> after the bitmap is recycled? Would it be helpful to implement Weak
> references for this scenario?
>
>
>  to On Dec 19, 3:10 pm, shyama <shyama.asoka...@gmail.com> wrote:
> > I know this question has been asked over and over again in these
> > forums. But the reason I am posting it again is because I have nt
> > received a clear answer to it. It would be great if someone could help
> > me with this.
> >
> > I am current using opencv + android to make some simple app that will
> > do image manipulation like edge, blur etc and display it using an
> > imagebutton. The images are being loaded through the gallery. There
> > are 3 buttons to blur, edge, and reset to original which will display
> > the modified image on the image button. given below is my code.
> >
> >     package com.example;
> >
> >     import java.io.File;
> >     import java.io.FileNotFoundException;
> >     import java.io.IOException;
> >     import java.io.RandomAccessFile;
> >     import java.nio.Buffer;
> >     import java.nio.MappedByteBuffer;
> >     import java.nio.channels.FileChannel;
> >     import java.nio.channels.FileChannel.MapMode;
> >
> >     import android.app.Activity;
> >     import android.content.Intent;
> >     import android.graphics.*;
> >     import android.graphics.Bitmap.Config;
> >     import android.net.Uri;
> >     import android.os.Bundle;
> >     import android.os.Debug;
> >     import android.provider.MediaStore;
> >     import android.util.Log;
> >     import android.view.View;
> >     import android.view.View.OnClickListener;
> >     import android.widget.Button;
> >     import android.widget.ImageButton;
> >     import android.widget.ImageView;
> >
> >     import org.opencv.core.*;
> >     import org.opencv.imgproc.*;
> >     import org.opencv.android.*;
> >     import org.opencv.highgui.*;
> >
> >     import dalvik.system.VMRuntime;
> >
> >     import android.graphics.Color;
> >
> >     public class ImageProcessing extends Activity implements
> > View.OnClickListener{
> >
> >     private ImageButton choice;
> >     private Button Blur;
> >     private Button Canny;
> >     private Button Reset;
> >     Uri photoUri;
> >     static private Bitmap bitmap;
> >     static private Bitmap mutBitmap;
> >
> >     private static String TAG = "ImageProcessing";
> >     private static int TAKE_GALLERY_REQUEST = 2;
> >     /** Called when the activity is first created. */
> >     @Override
> >     public void onCreate(Bundle savedInstanceState) {
> >     super.onCreate(savedInstanceState);
> >     setContentView(R.layout.img);
> >
> >     choice = (ImageButton) findViewById(R.id.imagechoice);
> >
> >     Blur = (Button) findViewById(R.id.Blur);
> >     Canny = (Button) findViewById(R.id.edge);
> >     Reset = (Button) findViewById(R.id.reset);
> >
> >     choice.setOnClickListener(this);
> >     Blur.setOnClickListener(this);
> >     Canny.setOnClickListener(this);
> >     Reset.setOnClickListener(this);
> >
> >     }
> >     @Override
> >     public void onClick(View v) {
> >
> >     if(v.getId() == R.id.imagechoice)
> >     {
> >      Intent pickPhoto = new Intent(Intent.ACTION_PICK);
> >      pickPhoto.setType("image/*");
> >      startActivityForResult(pickPhoto, TAKE_GALLERY_REQUEST);
> >     }
> >     if(v.getId() == R.id.Blur)
> >     {
> >
> >       if(mutBitmap != null)
> >         mutBitmap.recycle();
> >       mutBitmap = bitmap.copy(Config.ARGB_8888, true);
> >       choice.setImageBitmap(mutBitmap);
> >       Mat mImg = Utils.bitmapToMat(mutBitmap);
> >       Size ksize = new Size(15,15);
> >       Imgproc.blur(mImg, mImg, ksize);
> >       mutBitmap.recycle();
> >       mutBitmap = Bitmap.createBitmap(mImg.cols(), mImg.rows(),
> > Bitmap.Config.ARGB_8888);
> >       Utils.matToBitmap(mImg, mutBitmap);
> >       choice.setImageBitmap(mutBitmap);
> >     }
> >     if(v.getId() == R.id.edge)
> >     {
> >       if(mutBitmap != null)
> >         mutBitmap.recycle();
> >       mutBitmap = bitmap.copy(Config.ARGB_8888, true);
> >       choice.setImageBitmap(mutBitmap);
> >       Mat mImg = new Mat();
> >       mImg = Utils.bitmapToMat(mutBitmap);
> >
> >       /**Converting to grayscale**/
> >       Mat mGray = new Mat(mImg.rows(), mImg.cols(), CvType.CV_8UC1,
> > new Scalar(0));
> >       Imgproc.cvtColor(mImg , mGray, Imgproc.COLOR_BGRA2GRAY, 4);
> >       /**Applying Canny**/
> >       Imgproc.Canny(mGray, mGray, 80, 90);
> >
> >       //Converting back to 4 channel image
> >       Imgproc.cvtColor(mGray , mImg, Imgproc.COLOR_GRAY2RGBA, 4);
> >       mutBitmap.recycle();
> >       mutBitmap = Bitmap.createBitmap(mImg.cols(), mImg.rows(),
> > Bitmap.Config.ARGB_8888);
> >       Utils.matToBitmap(mImg, mutBitmap);
> >       choice.setImageBitmap(mutBitmap);
> >     }
> >     if(v.getId() == R.id.reset)
> >     {
> >       choice.setImageBitmap(bitmap);
> >     }
> >     }
> >     @Override
> >     protected void onPause() {
> >     super.onPause();
> >     Log.v(TAG,"on pause called");
> >
> >     Log.v(TAG,"Allocated memoryin on pause before recycle done:
> >     "+Debug.getNativeHeapAllocatedSize());
> >         choice.setImageBitmap(null);
> >         if(bitmap != null)
> >         {
> >             Log.v(TAG,"bitmap is not null");
> >             bitmap.recycle();
> >             if(bitmap.isRecycled())
> >                 Log.v(TAG,"bitmap is recycled");
> >             bitmap = null;
> >         }
> >
> >         if(mutBitmap != null)
> >         {
> >             mutBitmap.recycle();
> >             if(mutBitmap.isRecycled())
> >                 Log.v(TAG,"mutBitmap is recycled");
> >             mutBitmap = null;
> >         }
> >         Log.v(TAG,"Allocated memory on pause after recycle done:  "
> >         +Debug.getNativeHeapAllocatedSize());
> >
> >     }
> >     @Override
> >     protected void onResume() {
> >         super.onResume();
> >         choice.setImageBitmap(bitmap);
> >
> >     }
> >     @Override
> >     protected void onActivityResult(int requestCode, int resultCode,
> >             Intent intent) {
> >         super.onActivityResult(requestCode, resultCode, intent);
> >         Log.v(TAG,"onActivityResult called before loading bitmap,
> > Allocated
> >         memory:  "+Debug.getNativeHeapAllocatedSize());
> >
> >         if (resultCode == RESULT_OK) {
> >             photoUri  = intent.getData();
> >
> >             if (photoUri != null) {
> >                 try {
> >                      Log.v(TAG, "No crash 0");
> >                      bitmap =
> > Bitmap.createScaledBitmap(MediaStore.Images.Media.getBitmap(this
> >                             .getContentResolver(), photoUri), 300,
> > 400, true);
> >                      Log.v(TAG, "No crash 1");
> >                        Log.v(TAG,"onActivityResult called after
> > loading bitmap,
> >                        Allocated memory:
> > "+Debug.getNativeHeapAllocatedSize());
> >
> >                      choice.setImageBitmap(bitmap);
> >
> >                 } catch (Exception e) {
> >                     Log.v(TAG, "Unable to load image at path: " +
> > photoUri.getPath());
> >                 }
> >             }
> >         }
> >
> >     }
> >
> >     }
> >
> > bitmap - used for loading the image that user has selected from
> > gallery
> > mutBitmap - copy the image in bitmap and sets the mutable boolean to
> > true. so that I can manipulate the image
> >
> > I have included calls to Debug.getNativeHeapAllocatedSize() at four
> > places
> > 1)In onPause() before I recycle the bitmap(onPause is called when the
> > image button is clicked each time)
> > 2) after bitmap.recycle() is called in onPause()
> > 3) before new bitmap is loaded in onActivityResult()
> > 4) after new bitmap is loaded in onActivityResult()
> >
> > the following are the results in log cat:
> >
> > >12-19 13:22:20.629: VERBOSE/ImageProcessing(4551): on pause called
> > >12-19 13:22:20.629: VERBOSE/ImageProcessing(4551): Allocated memoryin
> on pause before recycle done:  5508024
> > >12-19 13:22:20.629: VERBOSE/ImageProcessing(4551): Allocated memory on
> pause after recycle done:  5508096
> > >12-19 13:22:39.279: VERBOSE/ImageProcessing(4551): onActivityResult
> called before loading bitmap, Allocated memory:  5507488
> > >12-19 13:22:39.279: VERBOSE/ImageProcessing(4551): No crash 0
> > >12-19 13:22:39.839: VERBOSE/ImageProcessing(4551): No crash 1
> > >12-19 13:22:39.850: VERBOSE/ImageProcessing(4551): onActivityResult
> called after loading bitmap, Allocated memory:  18246120
> > >12-19 13:22:51.329: VERBOSE/ImageProcessing(4551): on pause called
> > >12-19 13:22:51.329: VERBOSE/ImageProcessing(4551): Allocated memoryin
> on pause before recycle done:  18246704
> > >12-19 13:22:51.339: VERBOSE/ImageProcessing(4551): bitmap is not null
> > >12-19 13:22:51.339: VERBOSE/ImageProcessing(4551): bitmap is recycled
> > >12-19 13:22:51.339: VERBOSE/ImageProcessing(4551): Allocated memory on
> pause after recycle done:  18005032
> > >12-19 13:23:04.779: VERBOSE/ImageProcessing(4551): onActivityResult
> called before loading bitmap, Allocated memory:  18004408
> > >12-19 13:23:04.779: VERBOSE/ImageProcessing(4551): No crash 0
> >
> > As you can see, the second time I tried to load the same image the app
> > crashed. In onPause(), the nativeheapsize allocatted before and after
> > bitmap.recycle() is called is the same, even though bitma.isRecycled()
> > gives true.
> >
> > I also did adb shell dumpsys meminfo and this is what I got:
> >
> > When the image is loaded:
> >          ** MEMINFO in pid 3679 [com.example] **
> >
> >                     native   dalvik    other    total    limit
> > bitmap nativeBmp
> >
> >             size:    19240     2743      N/A    21983    24576      N/
> > A      N/A
> >
> >        allocated:    17871     2569      N/A    20440      N/A
> > 12678        0
> >
> >             free:      360      174      N/A      534      N/A      N/
> > A      N/A
> >
> >            (Pss):     1205     1048    16403    18656      N/A      N/
> > A      N/A
> >
> >     (shared dirty):     1660     4260     1424     7344      N/A
> > N/A      N/A
> >
> >     (priv dirty):     1168      832    15876    17876      N/A      N/
> > A      N/A
> >
> >  When the button is clicked again to load another image(i.e. onpause()
> > is called)
> >               ** MEMINFO in pid 3679 [com.example] **
> >
> >                     native   dalvik    other    total    limit
> > bitmap nativeBmp
> >
> >             size:    19240     2743      N/A    21983    24576      N/
> > A      N/A
> >
> >        allocated:     5186     2487      N/A     7673      N/A
> > 0        0
> >
> >             free:      361      256      N/A      617      N/A      N/
> > A      N/A
> >
> >            (Pss):     1205     1048     3718     5971      N/A      N/
> > A      N/A
> >
> >          (shared dirty):     1660     4260     1424     7344      N/
> > A      N/A      N/A
> >
> >          (priv dirty):     1168      832     3192     5192      N/
> > A      N/A      N/A
> > As you can see the allocated native heap size is changing in meminfo
> > when image is loaded and when onPause is called. But I am not sure why
> > the nativeheapallocated function in code still shows the same value.
> > I have 2 questions now:
> > 1) where is bitmap memory allocated. What happens when recycle()
> > function is called
> > 2) What is the native referred to in meminfo and in the
> > Debug.getNativeHeapAllocatedSize()? Are they different?
> >
> > If you think my approach is not the most effecient one I am also happy
> > to change it.
> >
> > Thanks,
> > Shyama
>
> --
> 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

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