[英]JavaCV Insufficient memory, failed to allocate memory
I am developing an OMR(Optical Mark Recognition) application using JavaCV,java interface for OpenCV.The application runs fine for 200 images but after that it fails to allocate memory for IplImage in my code.The allocation error comes when I try to clone imgx and assign it to imgxc1.Can you please suggest a programmatic fix for it? 我正在使用JavaCV,OpenCV的Java接口开发OMR(光学标记识别)应用程序。该应用程序可以很好地运行200张图像,但是此后它无法在我的代码中为IplImage分配内存。当我尝试克隆imgx时出现分配错误并将其分配给imgxc1。您能提出一个针对程序的修复程序吗? Increasing the heap size seems to be a temporary solution?
增加堆大小似乎是一个临时解决方案?
Here is the initialization code(where the exception occurs): 这是初始化代码(发生异常的地方):
protected boolean init () throws UnableToLoadImage{
imgx = new IplImage();
imgxc1 = new IplImage();
imgxd1 = new IplImage();
imgx = cvLoadImage(path+DR+filename);
if(imgx == null)throw new UnableToLoadImage(path+DR+filename);
//cvSaveImage("debug/"+filename, imgx);
imgxc1 = cvCreateImage(cvGetSize(imgx), imgx.depth(), imgx.nChannels());
imgxc1 = imgx.clone();//error comes here
imgxd1 = cvCreateImage(cvGetSize(imgx), IPL_DEPTH_8U, 1);
cvCvtColor(imgxc1, imgxd1, CV_BGR2GRAY);
return (imgx != null && imgxc1 != null && imgxd1 != null)?true:false;
}
Here is the cleaning up code: 这是清理代码:
public void release() {
if(imgx != null){
imgx.release();
imgxc1.release();
imgxd1.release();
cvReleaseImage(imgx);
cvReleaseImage(imgxc1);
cvReleaseImage(imgxd1);
}
}
Stack trace: 堆栈跟踪:
OpenCV Error: Insufficient memory (Failed to allocate 6454368 bytes) in cv::OutOfMemoryError, file ..\..\..\..\opencv\modules\core\src\alloc.cpp, line 52
at org.bytedeco.javacpp.opencv_core.cvCloneImage(Native Method)
at org.bytedeco.javacpp.helper.opencv_core$AbstractIplImage.clone(opencv_core.java:1005)
at com.omr.app.OmrModel.init(OmrModel.java:200)
at com.omr.app.OmrController$2.doInBackground(OmrController.java:328)
at com.omr.app.OmrController$2.doInBackground(OmrController.java:1)
at javax.swing.SwingWorker$1.call(Unknown Source)
at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
at java.util.concurrent.FutureTask.run(Unknown Source)
at javax.swing.SwingWorker.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Your code looks weird. 您的代码看起来很奇怪。 You're assigning
IplImage
objects to your variables, only to overwrite them instantly. 您正在将
IplImage
对象分配给变量,只是为了立即覆盖它们。 You're also leaking at least one presumably native resource in the following case: 在以下情况下,您还会泄漏至少一个本机资源:
imgxc1 = cvCreateImage(cvGetSize(imgx), imgx.depth(), imgx.nChannels());
imgxc1 = imgx.clone();//error comes here
The original imgxc1
object that was created with cvCreateImage
has no longer references to it, but you didn't release the resources. 使用
cvCreateImage
创建的原始imgxc1
对象不再引用它,但是您没有释放资源。
If how references work in Java is unclear to you, I'd suggest you do some work on that before continuing with your work. 如果您不清楚Java中引用的工作方式,建议您在继续工作之前先做一些工作。 You'll get rid of your redundant double assignment lines and the code will be clearer too.
您将摆脱多余的双重任务行,并且代码也将更加清晰。
Edit: Since I've already wasted time on this, let's go through init()
line by line. 编辑:由于我已经在此上浪费时间,让我们逐行通过
init()
。
protected boolean init () throws UnableToLoadImage{
imgx = new IplImage(); // Create a new IplImage() even though we won't use it
imgxc1 = new IplImage(); // Same here. Just food for the garbage collector
imgxd1 = new IplImage(); // Third completely unnecessary object creation
imgx = cvLoadImage(path+DR+filename); // Load an image, the previously created object in imgx is now GC food
if(imgx == null)throw new UnableToLoadImage(path+DR+filename);
//cvSaveImage("debug/"+filename, imgx);
imgxc1 = cvCreateImage(cvGetSize(imgx), imgx.depth(), imgx.nChannels()); // Create an image with native resources, previous object is GC food
imgxc1 = imgx.clone(); // Third time assignment to imgxc1, previous object isn't GC food since it holds native resources
imgxd1 = cvCreateImage(cvGetSize(imgx), IPL_DEPTH_8U, 1); // The first proper use of cvCreateImage
cvCvtColor(imgxc1, imgxd1, CV_BGR2GRAY); // Presumably ok
return (imgx != null && imgxc1 != null && imgxd1 != null)?true:false; // Doesn't need the ternary operator at all
}
The code shows a huge misunderstanding of Java, but if there hadn't been native resources involved, it would only result in some extra object creations which would then be handled by the garbage collector. 该代码显示了对Java的巨大误解,但如果没有涉及本机资源,则只会导致一些额外的对象创建,然后由垃圾收集器处理这些对象。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.