Classes that create new Mat should Mat.release() or memory leaks are created (Bug #3847)
Description
There are methods that create Mats as local variables and expect the JVM to GC them when they fall out of scope (there's not reference). This is OK for normal Objects, but due to Mat relying on finalize to clean up resources it will leak memory. Calling Mat.release is a work around. For example:
Imgproc.findContours
@
public static void findContours(Mat image, List<MatOfPoint> contours, Mat hierarchy, int mode, int method)
{
Mat contours_mat = new Mat();
findContours_1(image.nativeObj, contours_mat.nativeObj, hierarchy.nativeObj, mode, method);
Converters.Mat_to_vector_vector_Point(contours_mat, contours);
return;
}
Should be:
public static void findContours(Mat image, List<MatOfPoint> contours, Mat hierarchy, int mode, int method)
{
Mat contours_mat = new Mat();
findContours_1(image.nativeObj, contours_mat.nativeObj, hierarchy.nativeObj, mode, method);
Converters.Mat_to_vector_vector_Point(contours_mat, contours);
contours_mat.release();
return;
}
@
This will deallocate native memory right away.
Associated revisions
Merge pull request #3847 from mshabunin:android-build
History
Updated by Steven Goldsmith over 10 years ago
Consider the following source from https://github.com/sgjava/install-opencv/blob/master/opencv-java/src/com/codeferm/opencv/MotionDetect.java:
public static List<Rect> contours(final Mat source) {
// CHECKSTYLE:OFF MagicNumber - Magic numbers here for illustration
Imgproc.dilate(source, source, CONTOUR_KERNEL, CONTOUR_POINT, 15);
Imgproc.erode(source, source, CONTOUR_KERNEL, CONTOUR_POINT, 10);
// CHECKSTYLE:ON MagicNumber
final List<MatOfPoint> contoursList = new ArrayList<MatOfPoint>();
Imgproc.findContours(source, contoursList, HIERARCHY, Imgproc.RETR_TREE,
Imgproc.CHAIN_APPROX_SIMPLE);
List<Rect> rectList = new ArrayList<Rect>();
// Convert MatOfPoint to Rectangles
for (MatOfPoint mop : contoursList) {
rectList.add(Imgproc.boundingRect(mop));
// Release native memory
mop.release();
}
return rectList;
}
Even though I'm calling release on all the MatOfPoints there's still a native memory leak caused by Imgproc.findContours:
0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
0x201AEE47: cv::fastMalloc(unsigned long) (in /home/sgoldsmith/opencv-2.4.9/build/lib/libopencv_core.so.2.4.9)
0x2020C7C8: cv::Mat::create(int, int const*, int) (in /home/sgoldsmith/opencv-2.4.9/build/lib/libopencv_core.so.2.4.9)
0x20213946: cv::_OutputArray::create(int, int, int, int, bool, int) const (in /home/sgoldsmith/opencv-2.4.9/build/lib/libopencv_core.so.2.4.9)
0x20192464: cv::Mat::copyTo(cv::_OutputArray const&) const (in /home/sgoldsmith/opencv-2.4.9/build/lib/libopencv_core.so.2.4.9)
0x1FDA1EB4: vector_Point_to_Mat(std::vector<cv::Point_<int>, std::allocator<cv::Point_<int> > >&, cv::Mat&) (in /home/sgoldsmith/opencv-2.4.9/build/lib/libopencv_java249.so)
0x1FDA8217: vector_vector_Point_to_Mat(std::vector<std::vector<cv::Point_<int>, std::allocator<cv::Point_<int> > >, std::allocator<std::vector<cv::Point_<int>, std::allocator<cv::Point_<int> > > > >&, cv::Mat&) (in /home/sgoldsmith/opencv-2.4.9/build/lib/libopencv_java249.so)
0x1FDD0BFE: Java_org_opencv_imgproc_Imgproc_findContours_11 (in /home/sgoldsmith/opencv-2.4.9/build/lib/libopencv_java249.so)
Updated by Maksim Shabunin over 9 years ago
Issue has been transferred to GitHub: https://github.com/Itseez/opencv/issues/4806