JavaCV内存不足,分配内存失败
JavaCV Insufficient memory, failed to allocate memory
我正在使用 JavaCV 开发一个 OMR(光学标记识别)应用程序,java OpenCV.The 应用程序的接口可以很好地处理 200 张图像,但之后它无法为我的 code.The 当我尝试克隆 imgx 并将其分配给 imgxc1.Can 时出现分配错误,请您提出一个程序化修复建议?增加堆大小似乎是一个临时解决方案?
这里是初始化代码(出现异常的地方):
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;
}
清理代码如下:
public void release() {
if(imgx != null){
imgx.release();
imgxc1.release();
imgxd1.release();
cvReleaseImage(imgx);
cvReleaseImage(imgxc1);
cvReleaseImage(imgxd1);
}
}
堆栈跟踪:
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.doInBackground(OmrController.java:328)
at com.omr.app.OmrController.doInBackground(OmrController.java:1)
at javax.swing.SwingWorker.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)
您的代码看起来很奇怪。您将 IplImage
对象分配给您的变量,只是为了立即覆盖它们。在以下情况下,您还至少泄漏了一个可能的本机资源:
imgxc1 = cvCreateImage(cvGetSize(imgx), imgx.depth(), imgx.nChannels());
imgxc1 = imgx.clone();//error comes here
使用 cvCreateImage
创建的原始 imgxc1
对象已不再引用它,但您没有释放资源。
如果您不清楚 Java 中的引用是如何工作的,我建议您在继续您的工作之前做一些工作。您将摆脱多余的双重赋值行,代码也会更加清晰。
编辑:既然我已经在这上面浪费了时间,让我们逐行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
}
该代码显示了对 Java 的巨大误解,但如果没有涉及本机资源,它只会导致一些额外的对象创建,然后由垃圾收集器处理。
我正在使用 JavaCV 开发一个 OMR(光学标记识别)应用程序,java OpenCV.The 应用程序的接口可以很好地处理 200 张图像,但之后它无法为我的 code.The 当我尝试克隆 imgx 并将其分配给 imgxc1.Can 时出现分配错误,请您提出一个程序化修复建议?增加堆大小似乎是一个临时解决方案?
这里是初始化代码(出现异常的地方):
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;
}
清理代码如下:
public void release() {
if(imgx != null){
imgx.release();
imgxc1.release();
imgxd1.release();
cvReleaseImage(imgx);
cvReleaseImage(imgxc1);
cvReleaseImage(imgxd1);
}
}
堆栈跟踪:
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.doInBackground(OmrController.java:328)
at com.omr.app.OmrController.doInBackground(OmrController.java:1)
at javax.swing.SwingWorker.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)
您的代码看起来很奇怪。您将 IplImage
对象分配给您的变量,只是为了立即覆盖它们。在以下情况下,您还至少泄漏了一个可能的本机资源:
imgxc1 = cvCreateImage(cvGetSize(imgx), imgx.depth(), imgx.nChannels());
imgxc1 = imgx.clone();//error comes here
使用 cvCreateImage
创建的原始 imgxc1
对象已不再引用它,但您没有释放资源。
如果您不清楚 Java 中的引用是如何工作的,我建议您在继续您的工作之前做一些工作。您将摆脱多余的双重赋值行,代码也会更加清晰。
编辑:既然我已经在这上面浪费了时间,让我们逐行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
}
该代码显示了对 Java 的巨大误解,但如果没有涉及本机资源,它只会导致一些额外的对象创建,然后由垃圾收集器处理。