본문 바로가기

JavaCV/IplImage.release

IplImage.release

From: http://code.google.com/p/javacv/issues/detail?id=121


Reported by lumin.zh...@gmail.comOct 20, 2011
What steps will reproduce the problem?
1. More than 60000 images to be processed
2. run my program to only read the images with cvLoadImage
3.  Memory leak is detected. It's unlike the previous posts here. 


What is the expected output? What do you see instead?
I expect no memory increased. I have 12G memory, in several minutes, the java program will consume 11Gb and even after the program finished running successfully, the 11GB memory is still occupied (not by Java).

What version of the product are you using? On what operating system?
Ubuntu 11.04, OpenCV 2.3.1 without python and android support.  jdk 1.6

Please provide any additional information below.

My Code of the main thread (I only read images to test memory leak)

    public void run() {
    	logger.info("processing user: " + userId);
    	
    	for (String image: images) {
    		IplImage src = cvLoadImage(FilenameUtils.concat(inputDir, image), 1);
    			
    		src.release();
    		cvReleaseImage(src); // tried both separately or together, still doesn't work
    		System.gc();
    	}
    	
    	//queue.add(new UserImagesResult(userId, resultBuffer));
    	logger.info("Finished processing user: " + userId);
    	System.gc();
    }

BTW, I think most samples found in repository has the same problem. Since it's only for camera input or single images. no obvious slow down will be observed.



I want to make a complementary point. If I don't use cvReleaseImage or src.release(). it's even worse. The memory of the running Java thread will increase rapidly until the machine slow down to die. If I use src.create and release it with cvReleaseImage, the running Java thread will have no memory leak, we observe the memory of the running thread increases and decreases periodically.  But the problem reported here is still there, the total memory of the machine will be occupied and will not be released, even the java program finished running normally.
Comment 1 by lumin.zh...@gmail.comOct 20, 2011
I have also read the source code from javacv/opencv_highgui.

It seems the jni wrapper directly called the OpenCV's original code.
Probably it's a problem with the interface to the original C++ code. This is the reason why we only observe the global memory leak but not for the running Java thread.
Comment 2 by dav...@flipboard.comOct 20, 2011
I am seeing the same problem.  in my case, I load the image via IplImage.createFrom(java.awt.image.BufferedImage)
Comment 3 by lumin.zh...@gmail.comOct 20, 2011
oh, great. Actually I have tried to copy from BufferedImage one pixel by one pixel to the IplImage.

Now the problem has gone. At least, when java program terminates, the global memory will be freed.

Thank you again.

Comment 4 by project member samuel.a...@gmail.comOct 20, 2011
Yes, first things first, this may very well be a problem inside OpenCV. Could you try to run this cvLoadImage()/cvReleaseImage() loop in a C/C++ program and see what that gives? Thank you

BTW, we can also use IplImage.copyFrom() to copy from a BufferedImage.
Comment 5 by lumin.zh...@gmail.comOct 20, 2011
I didn't try that.  But I used OpenCV in C++ 4 years ago, no problem with that. And Also don't remember anyone report that bug in the group.

I guess for JavaCV, we should recommend people use IplImage.copyFrom for current version.
Comment 7 by project member samuel.a...@gmail.comOct 20, 2011
They changed most of the code (for the worse IMO) since OpenCV 2.0, so it would NOT surprise me to see issues like that, especially in the "deprecated" C API... ah well. But then again, it may be JavaCV for some reason. Let me know if you test it in C/C++, thanks.
Comment 8 by dav...@flipboard.comOct 24, 2011
I will try the C/C++ test.  BTW, in my app I am using HPROF and noticing a huge number of JNI global references building up over time (like almost 2 million).
Comment 9 by lumin.zh...@gmail.comOct 24, 2011
well, it seems that OpenCV didn't fix the problem of cvloadimage in C++. Instead we can use CVVimage:load.

Regarding my question, in javacv, I use iplimage.createfrom, there is still memory leak accumulated. It's really strange. For 20 test images, the memory will be released and back to original level after the program terminates. When I run it on 60000 images, it will occupy 10 G memory finally and not release the memory even after the program terminates.
Comment 10 by project member samuel.a...@gmail.comOct 28, 2011
I have just tried that cvLoadImage()/cvReleaseImage() loop in both C/C++ and Java here and I get no memory leak at all...

C/C++:
int main(int argc, const char *argv[]) {
    for (int i = 0; i < 1000000; i++) {
        IplImage *image = cvLoadImage(argv[1]);
        cvReleaseImage(&image);
    }
}

Java:
public static void main(String[] args) {
    for (int i = 0; i < 1000000; i++) {
        IplImage image = cvLoadImage(args[0]);
        cvReleaseImage(image);
        image = null;
        System.gc();
    }
}

using both lena.jpg and box_in_scene.png image files that come with OpenCV, no problem at all.

OpenJDK Runtime Environment (IcedTea6 1.9.10) (fedora-55.1.9.10.fc14-x86_64)
OpenJDK 64-Bit Server VM (build 19.0-b09, mixed mode)
and OpenCV 2.3.1 and JavaCV 2011-10-01

Let me know if you have more information that may be relevant. It seems to work fine here.
Comment 11 by the.duck...@gmail.comNov 1, 2011
I have memory leaks working with IplImage.create and BufferedImages, and a strange crash that always happens the 3rd time I call IplImage.create.

I attach my testsuite which isolates the issue as much as possible. 
main.java 
10.8 KB   View   Download
Comment 12 by project member samuel.a...@gmail.comNov 3, 2011
the.duckman, after removing the incorrect calls to `cvReleaseImage()`, the code you posted works just fine for me on the `lena.jpg` sample image file that comes with OpenCV... Do you still have issues after removing the calls to `cvReleaseImage()`?
Comment 13 by the.duck...@gmail.comNov 10, 2011
Cheers Samuel, sorry to take so long to get back to you.

It works (but causes a memory leak), I don't follow why the calls (line 156, 158) are incorrect. Can you elaborate a bit for me please?
Comment 14 by project member samuel.a...@gmail.comNov 10, 2011
cvReleaseImage() is just a normal function, it does not cancel the PhantomReference inside Pointer as set by IplImage.create() or IplImage.createFrom(). We need to call IplImage.release() for an IplImage image allocated that way, when we want memory to be deallocated "right now" that is. Otherwise, the garbage collector will deallocate memory, eventually, possibly not before the program terminates though...
Comment 15 by the.duck...@gmail.comNov 11, 2011
Thankyou your advice was most helpfull. I have use IplImage.release() and all issues were resolved.

-dm
Comment 16 by project member samuel.a...@gmail.comJan 8, 2012
So, is everything alright? Since I am unable to reproduce the problem, I am marking as invalid, but please let me know if you still have some issue, thank you.
Status: Invalid
Comment 17 by the.duck...@gmail.comJan 8, 2012
I run some pretty heavy unit tests on Win64. Currently able to process very
large quantities of data without any memory leak issues.

cheers.

-dm