【发布时间】:2014-01-28 21:43:52
【问题描述】:
我正在编写一个程序(C++,MinGW 32 位)来使用 OpenCV 函数批处理图像,使用 AngelScript 作为脚本语言。截至目前,我的软件有一些内存泄漏,这些内存泄漏很快就会增加(每个图像为 100-200 MB,我一次处理数千个)但我遇到了 Windows 似乎没有的图像正在释放我的程序使用的内存,直到重新启动。
如果我在大量图像上运行它,它会运行一段时间,最终 OpenCV 会抛出一个异常,说它内存不足。那时,我关闭程序,任务管理器的物理内存计量器回落到我开始之前的位置。但这里有一个问题 - 每次我尝试再次运行该程序时,它都会立即失败,无法为 OpenCV 分配内存,直到我重新启动计算机,此时它将再次适用于数百张图像。
Windows 是否可以通过某种方式保留该内存?或者是否还有其他原因导致 Windows 在重新启动之前无法为我的程序分配内存?这对我来说没有意义。
编辑: 我正在运行此程序的计算机是 Windows 7 64 位,具有 32 GB 内存,因此即使我的程序存在内存问题,它也只使用了少量可用内存.通常,该程序在退出之前会超过 1 GB 的内存。
编辑 2: 我也使用 FreeImage 来加载图像,我忘了提及。这是我的处理代码的基础:
//load bitmap with FreeImage
FIBITMAP *bitmap = NULL;
FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
fif = FreeImage_GetFileType(filename.c_str(), 0);
bitmap = FreeImage_Load(fif, filename.c_str(), 0);
if (!bitmap) {
LogString("ScriptEngine: input file is not readable.");
processingFile = false;
return false;
}
//convert FreeImage bitmap to my custom wrapper for OpenCV::Mat
ScriptImage img;
img.image = fi2cv(bitmap);
FreeImage_Unload(bitmap);
try {
//this executes the AngelScript code
r = ctx->Execute();
} catch(std::exception e) {
std::cout << "Exception in " << __FILE__ << ", line " << __LINE__ << ", " << __FUNCTION__ << ": " << e.what() << std::endl;
}
try {
engine->GarbageCollect(asGC_FULL_CYCLE | asGC_DESTROY_GARBAGE);
} catch (std::exception e) {
std::cout << "Exception in " << __FILE__ << ", line " << __LINE__ << ", " << __FUNCTION__ << ": " << e.what() << std::endl;
}
如您所见,唯一的指针是指向已释放的 FIBITMAP。
【问题讨论】:
-
等等,一个图片是100mb??
-
是的,这些图像是高分辨率未压缩的 TIFF。
-
你能提供一个最少的代码,或者至少是抛出异常的部分吗?你是如何读取和释放图像缓冲区的?
-
您确定是内存泄漏还是内存不足?仅当您已分配内存但不再持有对它的任何引用时,才会存在内存泄漏。这意味着这不是泄漏:
vector<double> vec; for(int i = 0; i < 10000000000000000000000; i++) { vec.push_back(i); }虽然这段代码可能会消耗你所有的内存。 -
看起来 OpenCV 在 GPU 上工作,所以我猜不是 Windows 本身负责内存分配。我不知道OpenCL内存分配是如何工作的,进程退出时没有自动释放可能是正常的。这也可以解释为什么你的最大容量是 1GB,我猜你的显卡只有 1GB 内存。
标签: c++ windows opencv memory-leaks mingw