0

I just started to play with OpenCV in Java and have problem with memory leaks. 30 times per second I read an image and saves it in a monitor class. At the same frequency my main thread clones the image and calls the moving method, in the class written bellow, with the clone as a attribute.

This method should basically do a low-pass filtering in the time domain why I want to constantly store the latest 10 images. I do this in an array which I shift back every iteration. The code attached is simplified to the problem.

The next step is that the the returned value is sent as an argument to a set-method in another object where is it assigned to a Mat object.

In this case I get a huge memory leak and the memory consumption increases with around 100MB per minute until it gets an out-of-memory-exception. The main problem seams to be the cloning, if I send the reference instead of cloning it then the problem is gone. The for-loop in the code given below makes the problem much worse (if i use cloning). Without the for-loop the memory leak is much smaller but still there. The same goes if I remove the movement.moving() call and just sends the clone to the set-method directly.

But i don't get why there is a memory leak. When i assign my variable to the new cloned object the old clone should be unreferenced and hence cleaned in the next GC?

private void update(){
    if (videoMon.haveImage()) {
        // Takes the image from the monitor
        Mat m = videoMon.getImageMat();
        // Sends a clone to the method stated given further down
        // and then to the setImage where it is assigned to the local object
        videoPanel.setImage(movement.moving(m.clone()));
        videoPanel.repaint();
    }
}

The other method

public class Movement {
    private static final int NBR_OLD_IMAGES = 10;

    Mat [] lastImages;

    public Movement(){
        lastImages = new Mat[NBR_OLD_IMAGES];
    }

    public Mat moving(Mat image){
        for (int i = NBR_OLD_IMAGES-1; i > 0; i--){
            lastImages[i] = lastImages[i-1];
        }
        lastImages[0] = image;

        return image;
    }
}
1
  • 2
    java's GC thinks, a Mat is a 20 byte entity (it does not see the c++ allocated bytes), so you have to call mat.release() manually wherever possible. Commented Nov 14, 2015 at 13:05

1 Answer 1

1

Use copyTo() instead of clone(), clone() doesn't release native memory, I had this same problem

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.