Android Studio still memory leak even release()

I am working on OpenCV in Android Studio. I convert RGB to HSV and find that app crash after running 30 seconds. I found that it is because of memory leak and someone say after adding .release() and System.gc(); will be ok. However, I still get memory leak after adding these two lines.

The memory profile picture

My code

public class MainActivity extends CameraActivity {

    CameraBridgeViewBase cameraBridgeViewBase;

    Mat bwIMG;
    cameraBridgeViewBase = findViewById(R.id.cameraViewer);
    cameraBridgeViewBase.setCvCameraViewListener(new CameraBridgeViewBase.CvCameraViewListener2() {
        @Override
        public void onCameraViewStarted(int width, int height) {

        }

        @Override
        public void onCameraViewStopped() {

        }

        @Override
        public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
            Mat image = inputFrame.rgba();
            bwIMG = new Mat();
            bwIMG.release();
            System.gc();
            Imgproc.cvtColor(image, bwIMG, COLOR_RGB2HSV);
            image.release();
            return bwIMG;
        }
    });
  }
}

It is fine when I comment the cvtColor line. How can I release the memory? Thanks.

because this is, where the actual memory allocation happens !
opencv’s c++ algorithms are using ‘lazy initialization’ a lot

tl:dr; try a pattern like this:

    Mat bwIMG; // class member (cached so we can keep the memory between onCameraFrame calls)
    ...

    @Override
    public void onCameraViewStarted(int width, int height) {
        // allocate an *empty* mat, let some func allocate the memory *later*
        bwIMG = new Mat();
    }

    @Override
    public void onCameraViewStopped() {
        // you still need to release every Mat, you called 'new' upon
        // only this will free actual (c++ allocated)pixels, 
        // system.gc() wont do this (sees only java mem)
        bwIMG.release();
    }

    @Override
    public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
        // 'borrowed' image, dont touch
        Mat image = inputFrame.rgba(); 

        // let algo allocate once, or reuse mem for dest mat
        Imgproc.cvtColor(image, bwIMG, COLOR_RGB2HSV);
        return bwIMG;
    }

Thanks for your reply. It works. I am trying to split channel but the same thing happens.

public void onCameraViewStarted(int width, int height) {
    bwIMG = new Mat();
    dst = new ArrayList<Mat>();  // dst is defined as List<Mat> dst
}

@Override
public void onCameraViewStopped() {
    bwIMG.release();
    for (int i = 0; i < dst.size(); i++){
        dst.get(i).release();
        }
    }
public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
    Mat image = inputFrame.rgba(); 

    Imgproc.cvtColor(image, bwIMG, COLOR_RGB2HSV);
    Core.split(bwIMG, dst);
    return dst.get(1);
    }

May I ask how to split channel correctly?

crosspost: