困扰好久的程序内存一直上涨的问题

LP2010 2011-02-13 02:55:16
环境:程序一直运行着,又不断的申请和释放资源,每周期涉及到的对象都蛮多,里面用到内存池
现象:程序每处理完一个周期,都会释放一些资源,但是不能全部释放完,导致物理内存和虚拟内存一直增加,但是到了一定的时间,十多天的时候,物理内存一下释放很多,但是虚拟内存还是缓慢增长
分析:1、内存池以前就有的,应该不会出现问题
2、用boundschecker检测,程序运行时候,还是能看到物理内存和虚拟内存不但增加,但是关闭程序时,boundschecker没有分析出来内存泄露
3、将所有NEW出来的对象的地址打印出来,再将所有释放的对象打印出来。比如:周一有些对象没有释放,但是在第二周期和第三周期能释放掉。这个逻辑是业务需求,不是程序问题。分析一段周期内的,申请释放资源情况,基本都能释放完,只有十多个对象没有释放完,这些有可能是下几个周期可以释放。
求救:请教各位高手,这个内存泄露可能由什么原因导致的,或者用什么方法检测更加方便准确,小弟在此先谢谢了。

能解决问题,分数不过可以追加!!
...全文
6569 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
taurusboy 2011-08-11
  • 打赏
  • 举报
回复
lz怎么解决的啊,分享一下啊~~我也正碰上跟你一样的情况呢~
LP2010 2011-03-14
  • 打赏
  • 举报
回复
问题解决了,谢谢各位建议。这些天有点忙,就没有登录论坛了,现在结贴散分了
yyysss520 2011-02-15
  • 打赏
  • 举报
回复
1.内存池 是固定大小,还是会动态增长和释放的?
2.检测你的第三方库的内存申请和释放情况。
3.换个内存检测工具试下。
anyingliesou 2011-02-15
  • 打赏
  • 举报
回复
有个有意思的现象。你把GDI的程序最小化,你会发现内存会一下子减少很多。再恢复窗体,内存才会一点一点涨回去。这里你要搞清楚内存和虚拟内存的区别.
如果你调用了第三方源码的话,看看是不是 原本变量有 自己的create\destroy功能。你用了new.
如果你调用了dll的话,是不是试图删除dll内部的数据了?
还有类似CString多次撤销的问题.
以上都需要小心一点.容易造成不易察觉的内存泄露.检查下.
nscboy 2011-02-15
  • 打赏
  • 举报
回复
出列new,delete等方式动态创建的对象会导致内存泄漏外.
使用GDI,句柄等不当的话也会导致资源泄漏.从而引发程序内存不断增长.最后甚至会导致资源耗光程序崩溃,甚至是系统崩溃.
delphiwcdj 2011-02-15
  • 打赏
  • 举报
回复
用boundschecker高级模式检测
qman007 2011-02-15
  • 打赏
  • 举报
回复
继续

建议你改写一个版本,完全使用对象池,再运行起来观察,如果问题依旧的话,则
只能是第三方二进制代码的问题了。
qman007 2011-02-15
  • 打赏
  • 举报
回复
为何不全部使用内存池呢?
确切的说应该全部使用对象池,对象在C++是class,C中是struct/union,
通过数组或双向链表来管理,

在应用程序初始化时不要怕浪费,尽可能让各个对象池中存在多的空闲对象,
至于具体数量多少就需要计算了(每个对象大小*数量/4096=该对象池占用虚拟内存页面个数,不整除需+1)
。一定要避免频繁的new/malloc和delete/free,因为堆上的碎片过多会导致虚拟页面增加
来满足申请要求。

如果完全采用对象池的话,你会看到程序完成各个对象池的初始化后内存占用会猛增,但之后基本
上会维持不动(java的jvm就是如此方式),而且基于内存的寻址访问要比频繁的从硬盘分配虚拟
页面再被换入RAM快上好几万倍,应用程序也会稳定健壮的运行,缺点就是多占用了计算机的内存
资源,但这点开销不算什么,现在的服务器硬件性能高的令人咂舌,牺牲一点内存占用无所谓的
luciferisnotsatan 2011-02-14
  • 打赏
  • 举报
回复
如果你的程序在结束时,回去delete那些对象。那么用工具是查不出来的。因为对象是被释放了。
看看代码,为什么有的对象要下几个周期才释放。之后的周期是否用到了这个对象?没用到就直接在本周期里释放。
食财物权情性 2011-02-14
  • 打赏
  • 举报
回复
LS蛮强大
LP2010 2011-02-14
  • 打赏
  • 举报
回复
感谢大家的帮忙,也不知道有没有什么好方法,我现在就只能一句代码一个逻辑的分析了,希望能找出原因所在
zh852 2011-02-13
  • 打赏
  • 举报
回复
我去年找内存泄露的问题找了2个月,说实话是挺纠结人的。一般的内存泄露问题都很容易找的,比如说new delete对应,free malloc对应啥的,
你这么做试试:

1.程序中是否用到了其他的库,你先查查看这些库是否有泄漏。写个测试程序一般就能知道了。
2.一层一层的排除,看泄露出现在哪部分,缩小范围之后,一行一行仔仔细细看,只要是程序中的逻辑关系,慢慢琢磨。我当时碰到这种情况,别人写的一个应用层的协议中有泄漏,找了很久才发现他new后,在最后进行delete时的逻辑有错误。
3.我当时为了检测内存泄露,boundschecker,purify(还有个不记得名字了,是个c++库),都用过,但是都没查出来,所以遇到这个得时候别迷信那些工具,很多东西查不出来的。你不妨把整个代码放开,拿张纸,握一支笔,将整个程序从前到后所有的逻辑关系,调用,运行过程写写,仔细分析下,也许有用,我当初找了一个多月时没搞出来,这样做的话,效果不错,这也许是没办法的办法,呵呵。
4.在编程思想这本书中,也介绍了一种方法,你不妨试试,网上相关的方法也能找到,基本上都是雷同的。貌似我记得是下卷,你翻翻,也许对你有用。

嘿嘿,希望对你有帮助!
futurepi 2011-02-13
  • 打赏
  • 举报
回复
保佑楼主早日解决问题
yanran_hill 2011-02-13
  • 打赏
  • 举报
回复
程序很大吗?有多少个模块,多少个函数?
你把每个函数单独提取出来,让测试人员好好的运行测试一遍,看一下运行前后堆栈的变化情况,应该就能找到问题了,显然你遇到的这个问题,不能使用功能代码分析的方法解决,白盒测试也许更有效
xwfde 2011-02-13
  • 打赏
  • 举报
回复
是否用到windows 画刷等GDI资源?是否用到playsound ?
mxzy55560593 2011-02-13
  • 打赏
  • 举报
回复
用_CrtSetDbgFlag检测嘛,看是不是内存泄露
bluesky12312388 2011-02-13
  • 打赏
  • 举报
回复
不一定是new内存导致的,可以看看是不是有些内核变量没有释放
chaoliu1024 2011-02-13
  • 打赏
  • 举报
回复
new完delete掉
DontKissBossAss 2011-02-13
  • 打赏
  • 举报
回复
手指头算效率最高。工具都死的。
bullbat 2011-02-13
  • 打赏
  • 举报
回复
bu dong bang ding

65,176

社区成员

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

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