使用vld检查内存泄露

黑娃 2013-03-14 06:32:19
请看伪代码
#include "vld.h"
...

int main()
{
//step1:
// 给一些全局变量分配内存

//step2:
for(;;)
{/* 服务器的逻辑 */}

//step3:
// 释放全局变量分配的内存
}

问题:
由于这是个逻辑服务器进程,所以永远走不到step3,那我用vld怎么捕捉内存泄露信息呢?
我现在都是在step2的时候把程序关闭了,就是右上角的x按钮,vld会给我很多泄露信息,但是我怀疑不准确。
我自己做了一个实验,就是用上例的三部写个简单例子,如果在第二步关闭程序的话,vld是不会给出任何输出的。
实际上第二步很复杂,多线程的程序,还有底层的socket封装、继承,共享内存,lua脚本载入等等,不知道vld是不是因为用了什么奇怪的模块才会打出一些我觉得不准确的泄露情报。

求指教,我怎么来检查这个程序的这个内存泄露情况比较靠谱?
...全文
716 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
jjk_by 2015-08-25
  • 打赏
  • 举报
回复
引用 12 楼 wuzhanhui 的回复:
char *pBuf = new char[200]; 只能检测这种内存泄露了, 不能检测下面这种泄露,哎这个vld不是传说中的那么好 CString reciveMsg=L"111"; reciveMsg.GetBuffer(0);
会自动回收的吧,当然不会有内存泄漏了~
wuzhanhui 2014-07-30
  • 打赏
  • 举报
回复
char *pBuf = new char[200]; 只能检测这种内存泄露了, 不能检测下面这种泄露,哎这个vld不是传说中的那么好 CString reciveMsg=L"111"; reciveMsg.GetBuffer(0);
赵4老师 2013-03-18
  • 打赏
  • 举报
回复
崩溃的时候在弹出的对话框按相应按钮进入调试,按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处。 判断是否越界访问,可以在数组的最后一个元素之后对应的地址处设置数据读写断点。如果该地址对应其它变量干扰判断,可将数组多声明一个元素,并设置数据读写断点在该多出元素对应的地址上。
赵4老师 2013-03-18
  • 打赏
  • 举报
回复
除了内存会泄漏,其它资源也会泄漏。 检查是否资源泄漏的办法之一: 在任务管理器 进程 查看 选择列 里面选择:内存使用、虚拟内存大小、句柄数、线程数、USER对象、GDI对象 让你的程序(进程)不退出,循环执行主流程很多遍,越多越好,比如1000000次甚至无限循环,记录以上各数值,再隔至少一小时,越长越好,比如一个月,再记录以上各数值。如果以上两组数值的差较大或随时间流逝不断增加,则铁定有对应资源的资源泄漏!
黑娃 2013-03-15
  • 打赏
  • 举报
回复
引用 7 楼 qq120848369 的回复:
汗, valgrind会让程序很慢,这一点你得搞明白。 正常跑到700M就不升了, 那一般是不会有泄露的。 挂valgrind做压力测试,内存基数本来就会高一些。 另外, 贴一下valgrind结果吧, 谁知道你说的泄漏到底是不是泄露
不好意思,我说的vld是visual leak defector。。。 结果太多了,txt都好几M,肯定是没有意义的信息。
qq120848369 2013-03-15
  • 打赏
  • 举报
回复
汗, valgrind会让程序很慢,这一点你得搞明白。 正常跑到700M就不升了, 那一般是不会有泄露的。 挂valgrind做压力测试,内存基数本来就会高一些。 另外, 贴一下valgrind结果吧, 谁知道你说的泄漏到底是不是泄露
黑娃 2013-03-15
  • 打赏
  • 举报
回复
引用 5 楼 ri_aje 的回复:
引用 3 楼 falcomavin 的回复: 引用 1 楼 ri_aje 的回复:服务器正常关闭的时候,step3 完全不执行吗?那 step3 有什么用,没执行对应的释放,当然会报泄漏的。 服务器在第二步没有退出循环的可能,所以所谓正常关闭服务器,都不会走到第三步,我试过的,比如在第三步加入写入文件之类的代码,没有执行到。 而第三步释放的是全局变量申请的内存,它们本就应该在程序运行……
看来事实正如你说。我尝试注视了第三步和第二步的代码,并严格控制第一步的分配内存流程,我一段一段注释了代码,观察vld的输出,问题出在了第一步分配某模块内存的时候,那个类继承了自封装的socket基础,只要让他执行,vld就不会打印出任何信息,同样的事情也发生在一个日志线程上,只要同意该线程运行,vld也打印空白信息。 所以我搞不懂了,到底什么地方招惹了vld,我自己写了个小例子尝试vld在多线程环境的表现,是没有问题的。 你对vld的使用是否有什么心得,可以提醒我的注意事项? 哦对了,还有一点可以说一下,该进程启动的时候要加载很多地图信息,如果我正常启动不用vld内存消耗在700mb左右,如果用了vld内存会增加到1.7G然后就卡住走不下去了,我之所以还能做上面的各种尝试,是因为修改了程序配置表,只加载了一个地图。
ri_aje 2013-03-15
  • 打赏
  • 举报
回复
引用 3 楼 falcomavin 的回复:
引用 1 楼 ri_aje 的回复:服务器正常关闭的时候,step3 完全不执行吗?那 step3 有什么用,没执行对应的释放,当然会报泄漏的。 服务器在第二步没有退出循环的可能,所以所谓正常关闭服务器,都不会走到第三步,我试过的,比如在第三步加入写入文件之类的代码,没有执行到。 而第三步释放的是全局变量申请的内存,它们本就应该在程序运行中一直存在,而我想检测……
我理解你的情况,但问题是 vld 估计没这么智能。它在系统过来收摊之前看一眼还有那些内存没释放,不可能去区分那些是放不放无所谓的内存,那些是真正需要 debug 的内存泄漏。然后成百上千的全打印出来,你怎么找有用的信息啊?可行的方法就是必须执行 step3 (甭管你是临时改一改,还是想什么歪招迫使程序执行 step3),这样那些疑似的内存泄漏就不会出现在 vld 的报告中了,剩下的(如果还有)才有用。
  • 打赏
  • 举报
回复
打log,在new和delete的地方打上log,log最好能加上函数名和文件名,查看log是不是成对。
黑娃 2013-03-15
  • 打赏
  • 举报
回复
引用 1 楼 ri_aje 的回复:
服务器正常关闭的时候,step3 完全不执行吗?那 step3 有什么用,没执行对应的释放,当然会报泄漏的。
服务器在第二步没有退出循环的可能,所以所谓正常关闭服务器,都不会走到第三步,我试过的,比如在第三步加入写入文件之类的代码,没有执行到。 而第三步释放的是全局变量申请的内存,它们本就应该在程序运行中一直存在,而我想检测的是第二步中有没有泄露,那些泄露才可能会使得消耗内存与日俱增。
ri_aje 2013-03-15
  • 打赏
  • 举报
回复
引用 6 楼 falcomavin 的回复:
引用 5 楼 ri_aje 的回复:引用 3 楼 falcomavin 的回复: 引用 1 楼 ri_aje 的回复:服务器正常关闭的时候,step3 完全不执行吗?那 step3 有什么用,没执行对应的释放,当然会报泄漏的。 服务器在第二步没有退出循环的可能,所以所谓正常关闭服务器,都不会走到第三步,我试过的,比如在第三步加入写入文件之类的代码,没有执行到。 ……
没用过 vld,不过这些内存泄露检测的软件都差不多,挂上以后运行程序都会很慢,有时候甚至原来的程序根本跑不动(感觉比 debug build 更慢),内存用量也会更大,cluster 上调程序更是指不上它们。所以我很少仰仗这些软件,一般都是 defensive programming,依赖 raii 这样的自动释放技术。 anyway,调内存泄露没什么太好的方法,最重要的就是细心(不要放过任何看似没问题的部分)和耐心(一个 bug 好几天很正常)。基本就是二分查找,就像你做的,一截一截注释排查代码。放开思路,别局限在常见的几种可能的错误类型中。比如,有时候指针强制类型转换错误,调用了错误的析构函数导致少执行了代码或者错误的成员函数覆盖了其他内存,也会引起泄露。
sduxiaoxiang 2013-03-14
  • 打赏
  • 举报
回复
进程结束 释放不释放都无所谓 反正有os
ri_aje 2013-03-14
  • 打赏
  • 举报
回复
服务器正常关闭的时候,step3 完全不执行吗?那 step3 有什么用,没执行对应的释放,当然会报泄漏的。

64,683

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧