在用OpenCV训练分类器(特别是训练Adaboost类型的分类器)的时候,当样本的数量特别大的时候,就会出现申请内存不够的情况,很早以前碰到过这样的情况,最近再训练的时候又出现了这样的情况,于是在网上找了一下解决方法。
首先给出我的配置吧,win7 64位 + vs2010 + opencv2.4.9,其实这个问题的产生应该只与系统有关系
本文的绝大部分是引用自博友lff0305的“使用LargeAddressAware压榨额外的用户态内存”,在此向其表示感谢!
一般情况下,无论在32位系统还是64位系统下,一个Win32用户进程可用的内存空间只有2GB少一点。那么,假设一个Win32程序内存不够用了,又不想(或者没办法)编译成X64的,怎么办呢,MS提供了一种方法,Linker中的LargeAddressAware参数。
启用它,可以获得额外的用户态内存。我在自己的X64系统下测试,如果没有启用,可以申请2GB不到;但是启动了这个参数,则可以申请将近4GB(因为还要受32位程序32位指针的限制):
程序很简单,如下:
- int _tmain(int argc, _TCHAR* argv[])
- {
- int c = 0;
- while (true) {
- void * p = malloc(1024 * 1024 * 32);
- if (p != 0) {
- c++;
- printf("alloc %d MB OK ", c * 32);
- } else {
- break;
- }
- }
- printf("alloc %d MB Totally ", c * 32);
- getchar();
- return 0;
- }
该程序如果不设置LargeAddressAware参数的话是1986MB。
我自己没有测试32位的系统,但是查到的资料说需要设置/3GB的启动参数。
对于已经存在的程序(没办法编译),可以使用VC中带的editbin.exe工具把该标志位打开:
这样这个程序也可以使用超过2GB的内存了。
同样对于一个exe,可以使用dumpbin.exe来验证。
如果dumpbin.exe /headers 文件名.exe
显示 Application can handle large (>2GB) addresses
那么说明该应用程序可以使用超过2GB的内存
当然这种方法的缺点:
1. 在64位系统上没办法使用超过4GB的内存;不过以前只能用2G,聊胜于无了;
2. 在32位系统上必须打开/3GB启动参数,为用户态程序预留3GB的内存
3. 对于带有自校验的程序,不适用,因为dumpbin相当于修改了这个exe,那么文件校验肯定是失败了;
总之最终的解决方法还是使用(或者编译出)X64的程序。-----------------------------------------------以上内容均引自使用LargeAddressAware压榨额外的用户态内存----------------------------------------
由于我的系统也是64位的,所以也没有对32位系统做相关的测试。
如果是等待编译的程序,则可以按照上面的方式在vs中进行修改;如果是已经编译好的程序,则可以用editbin.exe工具打开LargeAddressAware标志位。接下来主要是说一下用editbin.exe工具打开LargeAddressAware标志位。因为以前也没用过这玩意,所以刚开始看到了还不大会弄,看原博主的贴图中以为是直接把editbin.exe复制到相应的文件夹下就可以直接用了,可并不是这样,因为执行editbin还需要link.exe和MSPDB100.DLL,这在vs安装路径中很容易找到。后来发现可以直接通过Visual Studio命令提示来操作。可以在开始按钮中打开该命令提示,如图
在打开命令提示后,就可以用调用editbin.exe了,如图
将要已编译好的要修改的程序的完整路径放在最后面。执行完执行可以用dumpbin来查看,如图
看到显示 Application can handle large (>2GB) addresses,那么说明该应用程序可以使用超过2GB的内存。
最后附上一个链接,在这个链接里面可以看到win系统的相关内存限制说明,网址: