游戏卡顿白皮书 › L10 内存
内存碎片 Heap fragmentation
原因 ID mem-fragment · 主责 研发团队·服务器开发
在含图示和实验的完整版中打开此卡片 →
反复分配和释放会把空闲空间切得很碎,进程占用的内存会远多于实际使用量。
起因 多个线程长时间分配、释放大小不一的内存 → 结果 空闲空间零散分布、无法归还给 OS,占用像泄漏一样持续增长 → 画面表现 运行越久越会因 swap、内存不足而变慢,最后被强制终止
- 症状
- 慢动作, 掉线
- 因素
- 停顿
- 谁会遇到
- 全服
- 何时出现
- 开得越久越严重
- 负责方
- 主责 研发团队·服务器开发
- 研发团队要做的事
- 按大小分级的内存池,抗碎片的分配器(jemalloc、mimalloc 等)。
- 监控图上
- 缓慢爬升 · 进程内存(RSS)
- 查看位置
- 用同一版本启动两个服务器实例,只对其中一个用环境变量 MALLOC_ARENA_MAX 减少 glibc arena 数量,或换成 jemalloc 等其他分配器,对比几天内 pidstat -r 的 RSS
- 确认依据
- 人数、实体数相近,只有改过的那个实例 RSS 不再增长或大幅下降
- 排除依据
- 换了分配器照样上涨,是没有释放的内存,看“内存泄漏”(mem-leak)
- 确认手段
- 运维工具即可确认(无需游戏代码)
- 深入了解
- 曲线形态和泄漏一样,分析堆却找不到泄漏点。Linux 默认分配器(glibc)在线程多的服务器上尤其严重,仅仅换掉分配器,占用就可能大幅下降。
出处
- mallopt(3) — Linux manual page Linux man-pages
glibc malloc 为减少线程竞争,会创建多达 CPU 数若干倍的 arena,arena 越多内存占用越大(用 M_ARENA_MAX 限制,也可用环境变量 MALLOC_ARENA_MAX 设置) - jemalloc memory allocator jemalloc
注重避免碎片和并发扩展性的通用 malloc 实现 - pidstat(1) — Linux manual page sysstat
-r:各进程的 RSS(实际驻留在物理内存中的部分)
相关原因
同一层:L10 内存
其他层中同样导致“慢动作”的原因
查看含图示和实验的原卡片