nginx reload内存碎片问题-(一)

探讨了Nginx在reload后内存翻倍且无法释放的问题,分析了内存碎片产生的原因,通过使用malloc_trim()函数解决内存管理问题,并介绍了内存碎片率的计算方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

nginx reload内存碎片问题


相关资料

jemalloc、pmap、redis、systemtap、内存紧缩

问题现象

cache nginx 开启ip 库功能 占用700M 内存,reload 后内存翻倍,无法释放

root 9186 0.2 7.2 2150680 1786272 nginx master
reload 前 800M reload 后1.7G

根据描述有free,且多次reload 后内存不再增长;ip库使用系统malloc 和 free 没有使用内存池

问题原因

ip 库malloc 和free 大量紧邻操作可能导致glibc 内存管理合并机制没有归还给操作系统;解决方案使用malloc_trim() 函数归还内存给系统。

排查过程

首先验证是否存在内存泄漏

  1. 使用systemtap 脚本 排查没有存在内存泄漏,NGINX 确实有释放

  2. 使用pmap PID查看进程占用内存

    000000000017a0000 872628K rw---- [ anon ]
    xxxxxxxxxxxxxxxxx [ zero deleted ]

    reload 后, pmap 查看 从系统角度而言原先分配的内存确实还占用着,且又新分配了一段空间

结合ipku的频繁内存malloc 和 free 极有可能是内存碎片

000000000017a0000 872628K rw---- [ anon]
xxxxxxxxxxxxxxxxx xx      xx     [ zero deleted ]
00007fa033f930000 782890K rw---- [ anon]
xxxxxxxxxxxxxxxxx xx      xx     [ zero deleted ]
  1. 使用glibc 提供的malloc_trim 函数进行内存紧缩,内存得到释放。malloc_trim 是 GLIBC 4.0 以上提供的接口,紧缩为阻塞操作,可能影响服务时间,建议动态接口触发

扩展

C 等语言内存碎片如果不用内存池,会有碎片率问题:

  1. 如何计算内存碎片率
    redis 是如何计算内存碎片率没有深入研究过。但是像squid 类似的软件,对malloc 有做一层封装xmalloc,那么只需要统计(xmalloc-xfree)获得squid 内部的分配数 除以 jemalloc 的malloc static分配数 即可得到底层系统库内存碎片率,前提要求只有squid 才用到了jemalloc 采用静态库接口yes_jemalloc 而其他so 用的是glibc,算起来会比较准确
  2. 深入研究
    redis 有内存碎片查看接口,redis4 支持内存碎片清理、redis5 出了主动碎片整理V2 更好的内存统计报告、jemalloc5.1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值