在上周客户反馈了一个问题,大概意思是在他windows上安装的识别软件中,识别一百多张内容比较复杂的图片时,出现了“刚开始识别的没问题,但是识别到100来张时发现之后的图片都不识别了,没有识别结果”。

接收到问题立马就着手调试、重现,因为这是很早之前的代码了,由于不熟的缘故刚开始浪费了比较多的时间在搭建环境上(VS2015),不过还好,这个代码一测就测出了问题,还真有这BUG。下面是调试这个bug的详细步骤。

调试发现我的电脑上用客户的图片测试,虽然中间也走了一些弯路,费了一些功夫,不过最后发现会经常在识别到80张左右的时候跳过识别步骤,自然将问题定位到了识别的模块中。步进调试,继续将问题定位在识别之前的一个读取XML文件的步骤中,定位的问题代码如下:

MSXML2::IXMLDOMDocumentPtr   XmlPtr = NULL;
hr = XmlPtr.CreateInstance(_T("Msxml2.DOMDocument.4.0"));
hr = XmlPtr->load(_variant_t(strOCRName));

最后的那句代码返回值有问题,后续代码抛异常,这是当时发现的直接原因。

发现这个问题后,经网上查找官方文档,使用相关方法(具体查找xml执行错误的方法见我的另一篇博客地址:MSXML错误输出)分析了XML加载文件错误码和错误的原因,得到“0x8007000e,内存资源不足,无法完成此操作”,也就是系统的分配内存资源不足以支持当前程序在做一些消耗内存资源的操作了。于是临时想了几种解决方案:1.查找是不是有内存没有释放掉,定位问题所在;2.有没有可能在抛异常时,清理掉无用的内存占用,或者采用一种内存更优化的机制;3.会不会跟32位程序有关,寻址有限?;4.增加可用内存(如使能项目属性中的最大内存值>2G(设置方法:VS2015 win32程序使用大内存 (>2GB)设置),增加系统虚拟内存等);

经过尝试和权衡,最终还是没有用后三种(竟然还研究了半天C++内存池,有一篇资料讲的很不错:https://www.ibm.com/developerworks/cn/linux/l-cn-ppp/index6.html),因为毕竟治标不治本,而且客户当前也不是很捉急。

经过各种查找资料、各种咨询,也没解决。当时想着用MessageBox弹出错误的原因和错误码,在虚拟机上试试。这一试就尴尬了,虚拟机上竟然没问题?(我的电脑是系统WIN10-内存8G-硬盘1T,虚拟机系统WIN7-内存1G-硬盘40G)

奇了怪了,再次在物理机上调试,正常出错,但是竟然不弹出提示框。GetlastError呗,(GetLastError返回值及其含义)返回值:1158,表示当前程序已使用了 Window 管理器对象的系统允许的所有句柄。这表明什么?这说明系统给这个应用分配的句柄资源被消耗完了,查资料(相关资料见地址:windows资源管理(内核对象/GDI对象/user对象))发现windows编程中有三种对象是windows系统资源管理的,内核对象、GDI对象、User对象,其中GDI对象和User对象是有数量限制的(最高10000)。知道了这个,赶紧就打开任务管理器,查看我程序发生异常时,GDI对象和User对象有没有明显增长。

令人惊喜,找到问题所在了,如下图。

User对象涨到了10000封顶,步进调试发现在某一步骤中识别一次对象数量就增加120多,怪不得提示内存资源不足呢。接下来就查查这User对象有哪些方法,是不是有啥创建的没销毁的,查找官方文档:User对象​​​​​​​ 。

官方文档介绍的很清晰,有对应的创建方法就必须要对应的销毁掉。继续debug呗,皇天不负有心人,这代码架构很好,当时是真不好找啊,有问题的部分代码如下:

定睛一看,还真没有用销毁的方法,修改:在hwnd生命周期结束时,调用DestroyWindow(hwnd)销毁掉即可。

编译运行,试上他200张,自然结果完美运行不出错。

这次经历很有启发,还是要多看官方文档,而且找BUG千万不能放过任何一个小问题,只要有一点不对劲的就要抓住(因为在调用xml的load方法时,资料上说返回值是0是正确值,然而我试了数十次结果都是-1才是正确的返回,0才是错误的返回),还要多问,刚接手的代码就得多问,不能一个人钻。

但是还有一点不理解:为什么win7上测试程序,user对象超出10000限制了,还是能正常识别呢?希望有了解的大佬们不吝赐教!

VC++“内存资源不足,无法完成此操作”——解决的心路历程(User对象)相关推荐

  1. C++ 以智能指针管理内存资源

    1.简介 C++ 作为一门应用广泛的高级编程语言,却没有像 Java.C# 等语言拥有垃圾回收(Garbage Collection )机制来自动进行内存管理,这也是C++ 一直被诟病的一点.C++ ...

  2. 如何使用阿里云容器服务保障容器的内存资源质量

    作者:韩柔刚(申信) 背景 云原生场景中,应用程序通常以容器的形式部署和分配物理资源.以 Kubernetes 集群为例,应用工作负载以 Pod 声明了资源的 Request/Limit,Kubern ...

  3. W3wp.exe占用CPU及内存资源

    问题背景 最近使用一款系统,但是经常出现卡顿或者用户账号登录不了系统.后来将问题定位在了服务器中的"w3wp.exe"这个进程.在我们的用户对系统进行查询.修改等操作后,该进程占用 ...

  4. VC内存泄露检查工具:VisualLeakDetector

    From: http://www.xdowns.com/article/170/Article_3060.html 初识Visual Leak Detector        灵活自由是C/C++语言 ...

  5. Linux下如何查看哪些进程占用的CPU内存资源最多

    linux下获取占用CPU资源最多的10个进程,可以使用如下命令组合: ps aux|head -1;ps aux|grep -v PID|sort -rn -k +3|head linux下获取占用 ...

  6. 大内存 php 干什么好 centos,解决CentOS7中php-fpm进程数过多导致服务器内存资源消耗较大的问题...

    前言: 最近服务器内存使用率一直居高不下,检查之后发现可能和php-fpm进程数过多有关.本文记录了我优化php-fpm配置文件的过程并补充了一些和php-fpm有关的知识. 什么是php-fpm: ...

  7. 【巧用自带清空内存命令 一键释放内存资源】

    在日常使用中,如果本本运行时间长变得很慢,我们通常绿色系统收藏都是直接重启系统那就可以恢复速度,系统吧告诉你通过重启会恢复速度是因为内存缓存被清空了,其实借助系统自带清空内存命令,无需重启即可一键释放 ...

  8. FLAASH大气校正过程中内存资源不足解决方法

    数据介绍及数据其他操作详见此博客 ENVI5.3.1使用Landsat 8影像进行预处理及分析实例操作 20220212更新: 注意FLAASH大气校正的海拔,如果设置为0也是有可能报错的(我在做海面 ...

  9. linux 进程内存排行,linux下获取占用CPU/内存资源最多的10个进程[转自亿唐网]

    inux下获取占用CPU资源最多的10个进程,可以使用如下命令组合: ps aux|head -1;ps aux|grep -v PID|sort -rn -k +3|head linux下获取占用内 ...

最新文章

  1. C++标准库中各种排序归纳
  2. php基于laravel框架的批量插入操作
  3. Java二十三设计模式之-----原型模式
  4. 输出所有的合法的括号组合
  5. C语言宏与单井号(#)和双井号(##)
  6. [原]那些年整理的Linux常用命令,简单明了
  7. Redis之缓存设计
  8. 在finally块中使用try catch,并且catch的时候抛出异常的一个问题
  9. gog 中 git提交push到远程时出现error: RPC failed; HTTP 413 curl 22
  10. UCI数据集汇总及描述
  11. 关于开发板不断eth0: link up, 100Mbps, full-duplex, lpa 0x45E1 eth0: link down的问题
  12. python中的序列化与反序列化_Python之序列化与反序列化(pickle模块与json模块)...
  13. 笔记——数据归一化 scikit-learn中的Scaler
  14. 同一台电脑安装两个版本的jdk和jre
  15. linux 格式化 sda,linux – 如何将/ dev / sda挂载并格式化为不同的/ dev / name?
  16. 【Python】爬取金庸射雕英雄传连载版以及金庸作品里所有江湖门派
  17. 合工大c语言课后作业,填空类 合工大C语言题库
  18. 韩国瑜上任后 高雄六合夜市摊位出租率上升租金看涨
  19. 用Python设计第一个游戏,小插曲之变量和字符串(课堂笔记)
  20. 手把手教你编写脚本批量实现k8s镜像部署

热门文章

  1. Bernstein基函数及其性质 matlab实现
  2. Git和Github的使用
  3. 自动登录XP其实很轻松
  4. 马来西亚理科大学计算机专业雅思,【马来西亚理科大学本科雅思成绩要求】 - 马来西亚留学联盟...
  5. MySQL---- 自定义函数(FUNCTION)
  6. 讲解NRF24L01P无线收发模块(转载)
  7. ASEMI大功率场效应管和三极管的区别
  8. Windows中Nginx下载、安装、配置
  9. Java学习笔记(九)抽象类
  10. C语言代码质量与架构调整(三)