한국어English日本語简体中文繁體中文DeutschไทยTiếng ViệtРусскийPortuguês (Brasil)EspañolBahasa Indonesia

游戏卡顿白皮书 › L10 内存

swap Swapping

原因 ID mem-swap · 主责 运维团队·系统运维 · 配合 研发团队·服务器开发

在含图示和实验的完整版中打开此卡片 →

内存不足时,OS 会把一部分内存换出到磁盘。之后每次用到这部分内存,都要等待比内存慢 1,000 倍以上的磁盘。

起因 内存用量超过物理内存 → 结果 OS 把一部分换出到磁盘,需要时再读回来 → 画面表现 tick 耗时暴涨到数百 ms,这台服务器上的所有玩家都出现慢动作、卡住

症状
慢动作, 卡住
因素
停顿
谁会遇到
全服
何时出现
开得越久越严重, 晚高峰
负责方
主责 运维团队·系统运维 · 配合 研发团队·服务器开发
研发团队要做的事
给进程内存占用设上限(堆大小等),排查泄漏。
运维团队要做的事
游戏服务器配置为不使用 swap,靠内存告警应对;关闭 swap 后内存一旦不足进程就会被强制终止(OOM),所以物理内存要比峰值用量留足余量。
数值参考
读内存约 100 ns,从 SSD 读回约 100 µs(1,000 倍),经网络访问的云盘约 1 ms(1 万倍),HDD 约 10 ms(10 万倍)。
监控图上
缓慢爬升 · swap 用量、换入/换出
查看位置
把 vmstat 1 的 si、so 列(每秒从 swap 读入、换出到 swap 的量),/proc/pressure/memory 的 some、full(因等待内存而停顿的时间占比),以及游戏服务器进程 pidstat -r 的 majflt/s(必须从磁盘读入的缺页)与 tick 耗时叠加对照
确认依据
卡顿时刻 si 大于 0,游戏服务器的 majflt/s 和 memory 的 full 值一起上升
排除依据
si、so 为 0,内存压力(PSI)也接近 0,则与 swap 无关。没有 swap 而 majflt/s 和 PSI 上升,说明内存耗尽、正在重新读入代码页,要先腾出内存
确认手段
运维工具即可确认(无需游戏代码)
深入了解
带 GC 的服务器回收时要读遍堆的各个角落,所以哪怕只有一部分堆被换出,一次 GC 也可能拉长到几秒甚至几十秒。关闭 swap 后,不会经历因 swap 变慢的阶段,会直接进入强制终止(OOM),因此必须先留足空闲内存。即使没有 swap,内存接近耗尽时,OS 也会把可执行文件的代码页从内存中丢掉再重新读入,在被强制终止前,整台服务器可能会有一段时间严重变慢。

出处

  1. Designs, Lessons and Advice from Building Large Distributed Systems (LADIS 2009 keynote) Google
    “Numbers Everyone Should Know”:主存访问 100 ns,磁盘寻道 10 ms(2009 年数据)
  2. Documentation for /proc/sys/vm/ Linux kernel
    swappiness:swap 与回收文件页的相对开销;swap 是随机 I/O,代价高
  3. Concepts overview Linux kernel
    回收磁盘上有原件的页缓存和可换出的页,仍然不够时由 OOM Killer 杀掉进程
  4. Solidigm™ D7-P5520 and D7-P5620 Product Brief Solidigm
    服务器级 NVMe SSD 的 99.99% 延迟(four-nines latency)为 130 µs:SSD 单次读取约 100 µs 的依据
  5. Amazon EBS General Purpose SSD volumes AWS
    云上默认磁盘(gp3)的延迟为个位数 ms
  6. vmstat(8) — Linux manual page procps-ng
    si:每秒从 swap 读入的内存,so:每秒换出到 swap 的内存
  7. PSI - Pressure Stall Information Linux kernel
    /proc/pressure/memory 的 some(部分任务停顿的时间占比)和 full(所有任务同时停顿的时间占比)
  8. pidstat(1) — Linux manual page sysstat
    -r:majflt/s(必须从磁盘读入页面的缺页次数)

相关原因

同一层:L10 内存

其他层中同样导致“慢动作”的原因

查看含图示和实验的原卡片