ivan16luis / javacv

Automatically exported from code.google.com/p/javacv
GNU General Public License v2.0
0 stars 0 forks source link

Memory Leak in cvLoadImage or JavaCV (Big Issue, New problem) #121

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
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.

Original issue reported on code.google.com by lumin.zh...@gmail.com on 21 Oct 2011 at 12:21

GoogleCodeExporter commented 9 years ago
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.

Original comment by lumin.zh...@gmail.com on 21 Oct 2011 at 12:33

GoogleCodeExporter commented 9 years ago
I am seeing the same problem.  in my case, I load the image via 
IplImage.createFrom(java.awt.image.BufferedImage)

Original comment by dav...@flipboard.com on 21 Oct 2011 at 1:52

GoogleCodeExporter commented 9 years ago
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.

Original comment by lumin.zh...@gmail.com on 21 Oct 2011 at 2:43

GoogleCodeExporter commented 9 years ago
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.

Original comment by samuel.a...@gmail.com on 21 Oct 2011 at 6:22

GoogleCodeExporter commented 9 years ago
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.

Original comment by lumin.zh...@gmail.com on 21 Oct 2011 at 6:27

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
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.

Original comment by samuel.a...@gmail.com on 21 Oct 2011 at 6:33

GoogleCodeExporter commented 9 years ago
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).

Original comment by dav...@flipboard.com on 24 Oct 2011 at 5:33

GoogleCodeExporter commented 9 years ago
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.

Original comment by lumin.zh...@gmail.com on 24 Oct 2011 at 6:54

GoogleCodeExporter commented 9 years ago
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.

Original comment by samuel.a...@gmail.com on 28 Oct 2011 at 2:38

GoogleCodeExporter commented 9 years ago
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. 

Original comment by the.duck...@gmail.com on 2 Nov 2011 at 3:48

Attachments:

GoogleCodeExporter commented 9 years ago
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()`?

Original comment by samuel.a...@gmail.com on 4 Nov 2011 at 4:39

GoogleCodeExporter commented 9 years ago
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?

Original comment by the.duck...@gmail.com on 10 Nov 2011 at 3:20

GoogleCodeExporter commented 9 years ago
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...

Original comment by samuel.a...@gmail.com on 11 Nov 2011 at 3:47

GoogleCodeExporter commented 9 years ago
Thankyou your advice was most helpfull. I have use IplImage.release() and all 
issues were resolved.

-dm

Original comment by the.duck...@gmail.com on 11 Nov 2011 at 9:07

GoogleCodeExporter commented 9 years ago
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.

Original comment by samuel.a...@gmail.com on 8 Jan 2012 at 3:43

GoogleCodeExporter commented 9 years ago
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

Original comment by the.duck...@gmail.com on 8 Jan 2012 at 3:52