【一点点心得】处理 opencv insufficient memory

        最近在使用opencv的时候突然发现经过一段时间,就会报出 opencv error: insufficient memory 的问题,我反复检查代码,也没发现问题。 (事后证明这只是粗心而已)后来在拜读网上各个论坛的意见,并且尝试后,终于解决了问题,但却并不仅仅是代码或者工程设置上变化。

        首先必须澄清的是,这种错误也许有很多可能,可能是因为编译不是用的 x64, 可能是因为图形太大造成的,也可能在 Linker 的 system 下修改允许大内存地址就能解决等等。在这之前还是先假设为代码会出错吧,因为代码出错的可能性总是多种多样的。

        因为我的编译系统是 VS2015,也就暂时以此为根据吧。为了解决内存不够的问题,我查看了 VS2015 的 diagnostic tools,里面有 Process Memory 和 CPU 的用量观察。反复几次观察后,我发现我的内存在大概3分钟后升高到 3.3GB并崩溃。于是我使用了工具中的 take snapshot,会得到一个各个线程和变量使用堆栈资源的列表。

之后进入图片下部的这个Allocations或者Heap Size,进入后都是一样的,可以选择按照变量类型或者按照堆栈来看内容。

在堆栈图可以直接看到自己写的函数和变量,就对着Size最大的去就行了,因为既然是内存不足,肯定是撑爆了内存的家伙的错啊!但是要说的是,这样并不能直接精确地找到哪里出错,而是只能找到哪个函数出了错误。不过万幸的是,找哪个变量出错,不需要太麻烦,只要多看看 new 了些什么变量就行了。

我因为在无限循环里 new 了个unsigned char* 的矩阵,却没有把它在函数中delete掉,所以最后就被撑爆了。但是因为这是个返回值 unsigned char* 的函数,我没法在return之后再delete,于是写了两行代码作为替代。首先我把要delete的变量设为了全局变量,没初始化的那种。代码大致如下

unsigned char* imageArray; // 设置全局变量

unsigned char* transferImage() // 函数和返回值
{
	// 如果变量不为NULL,就清理其内存,并设置为NULL,这一步是为了防止旧内存堆积
	if (imageArray != NULL) 
	{
		delete[] imageArray;
		imageArray = NULL;
	}
	imageArray = new unsigned char[rows * cols * channels]; // 清理完后就能够名正言顺的生成新内存了
	unsigned char* row_buffer = imageArray;
	unsigned char* src_buffer = imageToCopy.ptr();
	// 将opencv的Mat图像内容copy进新的内存
	memcpy(row_buffer, src_buffer, imageToCopy.cols * imageToCopy.rows* imageToCopy.elemSize1()* imageToCopy.channels()); 
	return imageArray; // 返回图像指针
}
这么一弄之后,3.3GB的内存用量一下子下降到200MB,说明问题已经解决了。

这个方法可以反复查看内存的溢出。



  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值