OpenCV内存池管理(一)

OpenCV提供了一套高效的内存管理方案,提升了内存申请速率,减少了内存碎片,能够很好的提升程序的稳定性,同时支持线程同步。下面是对OpenCV内存管理源码中alloc.cpp的主要函数fastMalloc()fastFree()的解读研究。

1、启用内存池分配内存

OpenCV3.1中(包括之前的版本),默认是不启用内存池分配的。我的办法是对源码修改后重新编译。步骤如下:
  1. 在alloc.cpp中添加头文件#include <Windows.h>;
  2. 将宏CV_USE_SYSTEM_MALLOC改为0;
  3. 将AutoLock在该cpp中的名字替换为其他名字,如TAutoLock。
重新编译后就可以使用了。

2、原理说明

内存池首先分配了一个 巨大内存块,大小为1MB,然后在其中划分为一个个的 小块,每个小块大小为16KB,每个小块又可按照给定的内存大小分配表划分为29个 类型,将每个小块按类型进行大小 区段均分。申请内存时首先判断该大小的内存属于哪个类型,然后再在某个小块上进行分配工作。

3、基本结构及参数定义说明

  • 类型表binSizeTab
static const int binSizeTab[MAX_BIN+1] =
{ 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 128, 160, 192, 256, 320, 384, 480, 544, 672, 768,
896, 1056, 1328, 1600, 2688, 4048, 5408, 8128, 16256 };//29种类型
内存分配查询表MallocTables
struct MallocTables
{
uchar binIdx[MAX_BLOCK_SIZE/8+1];//对要分配的内存大小,能够以O(1)的时间复杂度找到对应的块类型大小
}

  • 最基本的内存块Block

struct Block{
    size_t signature;//标记,表明该内存块是该内存池分配的
    Block* prev; //上一个Block,不同情况下的意义不同
    Block* next; //下一个Block,不同情况下的意义不同
    Node* privateFreeList; //当前块的私有自由区段地址链表
    Node* publicFreeList; //
    uchar* bumpPtr; //当前小块中第一个可用区段地址,该指针只能往endPtr方向偏移累加
    uchar* endPtr; //当前小块中最后一个可用区段的尾地址
    uchar* data; //块中偏移头部结构后的数据区
    ThreadData* threadData; //线程数据指针
    int objSize; //当前块类型的大小,对应binSizeTab中的数值
    int binIdx; //当前块类型在内存分配查询表MallocTables中的下标
    int allocated; //该区块已分配的区段个数
    int almostEmptyThreshold; //阈值判断,与是否将该区块作为可用区块的判断有关
    CriticalSection cs; //临界区
}

  • 巨大内存块BigBlock

struct BigBlock
{
    BigBlock* next;//下一个巨大内存块
    Block* first; //巨大内存块中第一个区块地址
    int nblocks; //巨大内存块中区块个数
}

  • 内存池基本结构BigBlock

struct BlockPool
{
    CriticalSection cs;//临界区
    Block* freeBlocks; //指向内存池中自由块链表
    BigBlock* pool;//指向第一个巨大内存块地址
    int bigBlockSize;//巨大内存块的大小
    int blocksPerBigBlock;//未使用
}

  • 线程数据结构ThreadData

struct ThreadData
{
Block* bins[MAX_BIN+1][3];//用START、FREE控制每个区段的区块双向链表
static DWORD tlsKey;
}

4、内存池结构图




  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
OpenCV是一个开源的计算机视觉库,用于处理图像和视频数据。内存溢出是指程序在运行过程中申请的内存超过了系统所能提供的内存空间,导致程序崩溃或者运行异常。 在使用OpenCV时,可能会遇到内存溢出的问题,主要有以下几个原因: 1. 图像尺寸过大:如果处理的图像尺寸过大,会占用大量的内存空间。当内存不足以容纳图像数据时,就会发生内存溢出。可以通过降低图像分辨率或者使用图像压缩算法来减少内存占用。 2. 内存泄漏:在程序中没有正确释放已经申请的内存空间,导致内存不断累积,最终耗尽系统资源。可以通过检查代码,确保每次申请的内存都能正确释放。 3. 大量创建对象:如果在循环中频繁创建对象,会导致内存占用过高。可以考虑重用对象或者使用对象池来减少内存消耗。 4. 不合理的算法设计:某些算法可能会占用大量的内存空间,特别是在处理大规模数据时。可以考虑优化算法,减少内存占用。 为了避免OpenCV内存溢出的问题,可以采取以下措施: 1. 合理规划内存使用:在编写程序时,要合理估计所需内存空间,并及时释放不再使用的内存。 2. 使用合适的数据结构:选择合适的数据结构来存储和处理图像数据,避免不必要的内存占用。 3. 优化算法和代码:对于大规模数据处理,可以考虑使用分块处理或者并行计算等技术来减少内存占用。 4. 监控内存使用情况:通过工具或者代码监控内存使用情况,及时发现和解决内存溢出问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值