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