为什么linux下多线程程序如此消耗虚拟内存

本文作者在排查服务器内存优化问题时,发现一个现象:每当创建线程并分配小量内存时,虚拟内存会增加64M。经过一系列探索,发现是glibc的malloc机制在多线程环境下为了性能而使用arena内存池导致的。每个arena默认为64M,可通过设置环境变量限制arena数量,以减少不必要的内存占用。作者还提到,新版glibc的设计可能受到了tcmalloc的影响。
摘要由CSDN通过智能技术生成

最近游戏已上线运营,进行服务器内存优化,发现一个非常奇妙的问题,我们的认证服务器(AuthServer)负责跟第三方渠道SDK打交道(登陆和充值),由于采用了curl阻塞的方式,所以这里开了128个线程,奇怪的是每次刚启动的时候占用的虚拟内存在2.3G,然后每次处理消息就增加64M,增加到4.4G就不再增加了,由于我们采用预分配的方式,在线程内部根本没有大块分内存,那么这些内存到底是从哪来的呢?让人百思不得其解。

未命名_meitu_0

1.探索

一开始首先排除掉内存泄露,不可能每次都泄露64M内存这么巧合,为了证明我的观点,首先,我使用了valgrind

 

   1: valgrind --leak-check=full --track-fds=yes --log-file=./AuthServer.vlog &

 

 

然后启动测试,跑至内存不再增加,果然valgrind显示没有任何内存泄露。反复试验了很多次,结果都是这样。

 

在多次使用valgrind无果以后,我开始怀疑程序内部是不是用到mmap之类的调用,于是使用strace对mmap,brk等系统函数的检测:


   1: strace -f -e"brk,mmap,munmap" -p $(pidof AuthServer)


其结果如下:

 

   1: [pid 19343] mmap(NULL, 134217728, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0) = 0x7f53c8ca9000
   2: [pid 19343] munmap(0x7f53c8ca9000, 53833728) = 0
   3: [pid 19343] munmap(0x7f53d0000000, 13275136) = 0
   4: [pid 19343] mmap(NULL, 8392704, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, -1, 0) = 0x7f53d04a8000
   5: Process 19495 attached

 

我检查了一下trace文件也没有发现大量内存mmap动作,即便是brk动作引起的内存增长也不大。于是感觉人生都没有方向了,然后怀疑是不是文件缓存把虚拟内存占掉了,注释掉了代码中所有读写日志的代码,虚拟内存依然增加,排除了这个可能。

2.灵光一现

后来,

评论 25
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值