免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 5901 | 回复: 17
打印 上一主题 下一主题

Ubuntu下的多线程c++开发,遇到了一个内存释放的问题,求高人指点下 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-12-05 00:34 |只看该作者 |倒序浏览
本帖最后由 licaduo 于 2010-12-05 00:45 编辑

我最近在Ubuntu下做了一个c++程序,遇到一个内存释放的问题,纠结了一周了,实在搞不清楚,请高人指点下小弟。
我这边开发的程序处理流程大概如下: 程序是多线程架构,主线程负责网络接收,收到网络包之后,new一块内存存放这个数据包,把指针放入接收队列,业务处理线程从接收队列读取数据包,处理完后new一片内存存放需要发送的数据包,把刚才的数据包指针放入发送队列,然后释放刚才读取的接收数据包的指针。发送线程从发送队列中读取数据包,发送出去,释放发送数据包指针的内存。
    现在的问题是:在并发压力不大的时候,从top的结果看,进程的内存占用很正常,在处理请求包的时候占用内存增长,数据包处理完之后,占用的内存回到一个比较低的水平。但是在突发的压力比较大的时候,进程的内存占用增长,但是在系统压力回落到比较小的水平的时候,内存占用不下降,这样慢慢的进程占用的内存不断上涨。现在差不多进程运行一天内存涨150m,基本上3,4天我重启一次进程。我用Valgrind检测过程序没有内存泄露。另外我放入队列的数据结构中用到了string。   
     我开始使用的队列使用标准库的 queue实现,后来改成list实现,但是这个问题似乎没有什么改进。
    这两天从网上搜索了相关的问题,我怀疑我遇到的问题是不是与glibc的内存释放机制有关系。 之前同样的线程模型,在suse上运行似乎没什么问题,不过之前在suse上运行的程序中放入队列的数据结构中没有用到string,都是基本的int和char数组。这个问题纠结了一周了,实在搞不清楚为什么,代码上似乎没有什么明显的问题。

论坛徽章:
1
午马
日期:2013-08-23 23:39:47
2 [报告]
发表于 2010-12-05 00:58 |只看该作者
用用内存池试试吧,
new ,delete 本来操作的就是虚拟内存

论坛徽章:
0
3 [报告]
发表于 2010-12-05 10:07 |只看该作者
用内存池,比较麻烦的事情是,我不知道需要多大的内存池,在突发的大压力的时候会比较大,而平时会很小,这个内存使用最大值不好确定,另外引入内存池会不会引入新的风险?

论坛徽章:
1
午马
日期:2013-08-23 23:39:47
4 [报告]
发表于 2010-12-05 10:39 |只看该作者
还是多检查检查代码吧,没内存泄露的代码不代表资源没浪费。
你直接用new,delete就可以避免内存使用最大值不好确定的问题了吗?


只是提个建议,server端我没做过开发。

论坛徽章:
0
5 [报告]
发表于 2010-12-05 11:05 |只看该作者
我知道这个问题应该从代码的层面去解决,但是确实没有找到一个解决的方法。
       我最不解的是压力不大的时候内存占用很正常,但是在压力大的时候有问题。
       我之前的测试中有过一次这样的测试,测试过程如下:
       当时我用模拟程序在1分钟内给这个进程一次性发送600w个包,进程占用内存瞬间涨到1g,系统的cpu也是占用非常高,进程已经达到性能极限,但是在过了一段时间之后这些包都处理完之后内存还是不会下降。
       等到我再次发了一批10万的数据包给这个进程之后,内存又下降到200多m的水平。
      
       我之前以为内存占用上去就不下来,但是这个测试结果让我很不解。我之前在suse上用同样的线程模型做就没有问题。现在最麻烦的事情,我不知道该从哪个方面去考虑改进程序。对于引入内存池,我暂时不想去这么做,我觉得这个问题应该可以在不引入内存池的前提下解决,引入内存池会增加新的风险。

论坛徽章:
1
午马
日期:2013-08-23 23:39:47
6 [报告]
发表于 2010-12-05 11:39 |只看该作者
难道是内存碎片的问题?

论坛徽章:
0
7 [报告]
发表于 2010-12-05 18:54 |只看该作者
在这之前一直我没有用过ubuntu,是不是这个系统上有什么需要注意的事情我没有注意到?

论坛徽章:
26
处女座
日期:2016-04-18 14:00:4515-16赛季CBA联赛之深圳
日期:2020-06-02 10:10:5015-16赛季CBA联赛之广夏
日期:2019-07-23 16:59:452016科比退役纪念章
日期:2019-06-26 16:59:1315-16赛季CBA联赛之天津
日期:2019-05-28 14:25:1915-16赛季CBA联赛之青岛
日期:2019-05-16 10:14:082016科比退役纪念章
日期:2019-01-11 14:44:062016科比退役纪念章
日期:2018-07-18 16:17:4015-16赛季CBA联赛之上海
日期:2017-08-22 18:18:5515-16赛季CBA联赛之江苏
日期:2017-08-04 17:00:4715-16赛季CBA联赛之佛山
日期:2017-02-20 18:21:1315-16赛季CBA联赛之天津
日期:2016-12-12 10:44:23
8 [报告]
发表于 2010-12-05 19:04 |只看该作者
换个版本的操作系统试试 ~

论坛徽章:
0
9 [报告]
发表于 2010-12-05 19:16 |只看该作者
操作系统不能换,只能在这个下面改善。最郁闷的是,我现在没有思路,不知道从哪个方面去解决这个问题。

论坛徽章:
0
10 [报告]
发表于 2010-12-05 19:50 |只看该作者
只能用内存池,你用了stl,还得实现allocator。。。
你可以试试别的malloc实现,比如TCMalloc
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP