为什么free掉申请的空间后rss值不下降?

码农Ben 2015-03-02 04:25:50
我在做onvif服务端开发。
onvif服务端在响应请求时常常malloc一些64,128,256字节的空间,用完后free掉。
表面上看一切都很好,但用时间长后我的程序会被系统的oom killer(out of memory killer, 此程序在系统内存空间不足时自动删除占用系统rss最多的程序)杀掉。
使用ps -eo pid,rss,comm查看时发现onvif server的rss值只增不减。当每执行一条新的服务请求时rss值就增加一些。
时间长了rss占用能达到 22MB 那么多。
我打印了代码中的malloc和free,基本肯定了所有malloc的空间在一条服务请求结束后都有free。但申请的堆空间(heap)就是不还給系统。
请问我有什么方法可以释放已free的空间?
...全文
647 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
码农Ben 2015-03-10
  • 打赏
  • 举报
回复
原来gsoap的内存释放问题由来已久,网上很多人问,却没有看到解决方法。 官网上有这么一段话 “The gSOAP engine uses a memory management method to allocate and deallocate memory. The deallocation is performed with soap_destroy() followed by soap_end(). However, when you compile with -DDEBUG or -DSOAP_MEM_DEBUG then no memory is released until soap_done() is invoked. This ensures that the gSOAP engine can track all malloced data to verify leaks and double frees in debug mode. Use -DSOAP_DEBUG to use the normal debugging facilities without memory debugging. Note that some compilers have DEBUG enabled in the debug configuration, so this behavior should be expected unless you compile in release config. ” 但我确认了我的编译选项里没有-DDEBUG or -DSOAP_MEM_DEBUG 项,还特意在每次服务后面加入了soap_end(), 但问题依旧。 看来问题原因还隐藏在我不懂的地方。
码农Ben 2015-03-09
  • 打赏
  • 举报
回复
用valgrind调试了程序,没有发现有泄露。 有哪个Linux下比较好用的内存泄露检测工具?
码农Ben 2015-03-07
  • 打赏
  • 举报
回复
引用 10 楼 s120922718 的回复:
没用过你说的那个协议,稍微搜了一下看到一些内容 其实也不一定是你说的那个框架会有内存泄漏,可能是你所依赖的某个通信协议出现问题了 http://buffon.pixnet.net/blog/post/30986643-onvif-autopan-results-in-memory-leak http://bbs.csdn.net/topics/390837606
我也在确认中。第一个是台湾网站??打不开。已经连续搞了一周了。。。
__威少__ 2015-03-06
  • 打赏
  • 举报
回复
没用过你说的那个协议,稍微搜了一下看到一些内容 其实也不一定是你说的那个框架会有内存泄漏,可能是你所依赖的某个通信协议出现问题了 http://buffon.pixnet.net/blog/post/30986643-onvif-autopan-results-in-memory-leak http://bbs.csdn.net/topics/390837606
JoeBlackzqq 2015-03-06
  • 打赏
  • 举报
回复
引用 5 楼 chenben 的回复:
[quote=引用 2 楼 JoeBlackzqq 的回复:] 申请和free的内部细节,可能很多人都不知道,我也不知道。但是你能出现oom killer,说明一定是哪里有内存泄漏,仔细检查下吧。
oom killer不是很快出来的,有的机器2个月了都没问题,不过占用的heap都到了18mb以上了。都在我的程序那里。[/quote] 时间久才出现,有可能是因为每次泄漏的比较少,所以出现的时间需要很久。我就遇到过,每次泄漏不到100字节,跑3天左右被oom kill
码农Ben 2015-03-06
  • 打赏
  • 举报
回复
引用 7 楼 s120922718 的回复:
给你一篇文章,看对你有没有帮助 http://www.ibm.com/developerworks/cn/linux/l-cn-pagerecycle/
看了你提供的网站了,但难度挺大,不是我这种菜鸟可以实现的。非常感谢你。 另:有人说Onvif确实有内存泄露,拖了半年没解决。顿时泄气了。。。
__威少__ 2015-03-05
  • 打赏
  • 举报
回复
给你一篇文章,看对你有没有帮助 http://www.ibm.com/developerworks/cn/linux/l-cn-pagerecycle/
JoeBlackzqq 2015-03-04
  • 打赏
  • 举报
回复
申请和free的内部细节,可能很多人都不知道,我也不知道。但是你能出现oom killer,说明一定是哪里有内存泄漏,仔细检查下吧。
码农Ben 2015-03-04
  • 打赏
  • 举报
回复
我来简化一下问题。 我写了个简单的测试代码。 连续malloc和free 3次,在标有数字的地方设置断点,并在另一个控制台运行 pmap -x pid指令(程序pid通过ps指令获得)。 观察程序的内存占用情况。
int main()
{
    char a,b;
    char *p = NULL;   
// 1
    p = malloc(mem_size);   //  mem_size = 128 *1024,   128kB
// 2
    memset(p, 0, mem_size);   
// 3
    free(p);     
    p=NULL;
 // 4
    p = malloc(mem_size);
// 5
    memset(p, 0, mem_size);
// 6
    free(p);
    p=NULL;
// 7
    p = malloc(mem_size);
// 8
    memset(p, 0, mem_size);
// 9
    free(p);
    p=NULL;
// 10
}
值得注意的是,比较//3 和 // 4(即第一次free前后),得到比较正常的结果 在//3处执行pmap, 得到其中一行如下: Address Kbytes PSS Dirty Swap Mode Mapping 402f6000 144 140 140 0 rw-p [ anon ] 和//4处, Address Kbytes PSS Dirty Swap Mode Mapping 402f6000 12 8 8 0 rw-p [ anon ] 可以看出PSS已经降低,free正常。至于为什么没map在[heap]中,希望有大虾指教。 从第二次malloc开始,就map在heap中了。且free不掉。发现 // 6和 // 7打印的信息一样。即第二次free后,heap中的空间没有被free掉 Address Kbytes PSS Dirty Swap Mode Mapping 00fb0000 260 132 132 0 rw-p [heap] 之后// 8 ~ //10都保持这个输出。 问题是: 怎么第二次开始就free不掉申请的堆呢?难道每个进程只能free一次吗?不可能的吧。
码农Ben 2015-03-04
  • 打赏
  • 举报
回复
引用 3 楼 erhou134 的回复:
自己释放不代表 系统回收 不是free 就没了这么简单的机制的
引用 4 楼 s120922718 的回复:
操作系统对内存也的回收有两个策略 1:后台服务定期扫描 2:有进程申请内存的时候,内存不够,这个时候就会出发内存回收 猜测是你free之后,内存页还没有进行回收
谢谢两位的回答。由于有连续回复次数限制,我就一并回答了。 我也知道linux的堆管理不是那么简单。free只是將空间放回可用链上。 那些内存页放了一个月都不回收的,我看是有什么其他原因回收不了才对。 有没有办法让系统马上回收空闲内存?
码农Ben 2015-03-04
  • 打赏
  • 举报
回复
引用 2 楼 JoeBlackzqq 的回复:
申请和free的内部细节,可能很多人都不知道,我也不知道。但是你能出现oom killer,说明一定是哪里有内存泄漏,仔细检查下吧。
oom killer不是很快出来的,有的机器2个月了都没问题,不过占用的heap都到了18mb以上了。都在我的程序那里。
__威少__ 2015-03-04
  • 打赏
  • 举报
回复
操作系统对内存也的回收有两个策略 1:后台服务定期扫描 2:有进程申请内存的时候,内存不够,这个时候就会出发内存回收 猜测是你free之后,内存页还没有进行回收
空的 2015-03-04
  • 打赏
  • 举报
回复
自己释放不代表 系统回收 不是free 就没了这么简单的机制的

23,121

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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