最近,有部分越南的服务器内存不断上涨,怀疑是内存泄漏,因为框架提供的内存报告里,C 内存和 Lua 占用内存都不大,和 ps 里看的差好多。总内存在 12G 左右,C 和 Lua 的加起来约 4G,两者相差了 8G

经过一番排查,排除了混用 glibc malloc 和 jemalloc 的可能。于是 写了一个多线程的测试程序 ,由多个生产者 - 消费者线程对组成。生产者分配一个随机大小的内存(在 SIZE 范围内),然后 memset 将内存遍历一次,再将指针通过管道发给消费者。消费者拿到指针后,读一下指针的值,然后释放指针对应内存块。这个模型模拟了 skynet 的一个线程分配内存(消息),发给另一个线程消费(释放)的情况。在没有设置 jemalloc 的参数的情况下,这个例程的内存会逐渐涨到一个峰值,然后不再增大,但也不再减少。如果设定了例程里的 ABORT_COUNT,过了指定次数后不再进行内存分配,内存过几个小时也不会下降,这跟线上的情况类似

通过 MALLOC_CONF 环境变量,设置了 dirty_decay_ms:0,muzzy_decay_ms:0 以后,内存的峰值变低了,观察 top 命令的 RES 内存,明显低了不少。将选项换成了 background_thread:true,则例程即使不再分配内存,内存占用也会逐渐降低了。dirty_decay_ms 表示内存块从 dirty 状态移动到 muzzy 状态的时间,muzzy_decay_ms 是 muzzy 状态到释放给系统的时间。设为 0 以后行为会不一样,比如我两个参数都设置 10000ms,并不是 20 秒后就会还给系统。。

往后打算设置一下 background_thread:true,让内存不再使用时慢慢还给系统,避免 OOM Killer 找上门来杀进程