<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>交换 · XB 现场笔记</title><link>https://www.xbcatm.com/zh/tags/%E4%BA%A4%E6%8D%A2/</link><description>基于 HTTP、DNS、TLS、Caddy、SSH、发布与恢复的可复现运维现场笔记。</description><generator>Hugo</generator><language>zh-CN</language><atom:link href="https://www.xbcatm.com/zh/tags/%E4%BA%A4%E6%8D%A2/index.xml" rel="self" type="application/rss+xml"/><item><title>Swap 用回收成本换取驻留空间</title><link>https://www.xbcatm.com/zh/posts/swap-gives-memory-a-slow-extra-layer/</link><pubDate>Wed, 25 Nov 2026 00:00:00 +0000</pubDate><guid>https://www.xbcatm.com/zh/posts/swap-gives-memory-a-slow-extra-layer/</guid><description>分别观察交换占用、间隔流量与内存压力，区分磁盘交换、zram、zswap 和文件缺页。</description><content:encoded>&lt;p&gt;Swap 为 Linux 中适合换出的页面提供后备存储，让暂时不需要驻留的数据离开物理内存，把 RAM 留给活跃工作。但它不会让超出容量的工作集继续拥有内存访问速度。真正要问的是：回收是否腾出了空间，同时没有反复阻塞重要任务。交换占用、交换流量与应用进展，分别回答这个问题的一部分，不能拿其中一个数字概括全部情况。&lt;/p&gt;
&lt;h2 id="分清哪些页面可以移动"&gt;分清哪些页面可以移动&lt;/h2&gt;
&lt;p&gt;匿名内存经常使用交换，但并非唯一情况。配置允许时，tmpfs 和共享内存页面也能换出。普通文件支撑的干净页面通常可以丢弃，以后从原文件重读；脏文件页则需要适当写回。并非所有分配都可以回收，被锁定而禁止换页的内存还有另外约束。因此，“所有 malloc 分配的东西”不足以描述内核实际上能够移走哪些内容。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;vm.swappiness&lt;/code&gt; 在零到二百的文档范围内，表达交换与文件系统换页之间的相对成本；它不是达到某个 RAM 使用百分比后才开启交换的阈值。设为零也不等于在所有情形下禁用交换。如果压缩交换或更快的交换设备比文件系统换页便宜，大于一百的值可能合理，但适当取值取决于工作负载与存储。解释图表之前，应先读取实际配置，而不是默认每台机器都采用相同策略。&lt;/p&gt;
&lt;p&gt;zram 提供压缩内存块设备，可以配置为交换；zswap 则在交换页与后备交换设备之间提供压缩缓存。压缩本身消耗 RAM 和 CPU，效果也依赖数据内容。两者都没有通用的延迟、压缩比或安全超配比例。zswap 不是可以直接挂到 &lt;code&gt;/tmp&lt;/code&gt; 的文件系统；tmpfs 挂载具有自己的存储语义和容量约束，不能把名称相近的内存机制当成同一项功能。&lt;/p&gt;
&lt;h2 id="坏掉的样子"&gt;坏掉的样子&lt;/h2&gt;
&lt;p&gt;反复回收马上又要使用的页面，会造成严重停顿。原因可能涉及存储延迟与吞吐，也可能涉及回收工作、压缩开销、控制组限制和竞争 I/O。颠簸并不保证最终触发 OOM 杀进程，固定的交换速率也不是普遍适用的诊断线。应把内存压力与有效吞吐、响应时间放在同一个观察窗口比较，再决定主要瓶颈在哪里。&lt;/p&gt;
&lt;p&gt;交换已用量很大，可能只是早先事件留下的冷页面，不证明当前正在发生故障。相反，交换流量很小也不证明内存足够：交换可能未启用，工作负载可能碰到控制组上限，或者回收主要发生在文件页。主缺页计数上升也包括文件支撑的缺页，不能直接重新命名成换入次数。把相关指标当成同一个计数器，会让排查走向相反结论。&lt;/p&gt;
&lt;p&gt;计划中的交换文件可能因为布局或文件系统限制而无法启用。带空洞的文件不适用，但复制是否产生空洞，取决于具体工具、选项和源文件，不能一概而论。应检查已经激活的交换清单，不要假定配置文件里写过一行就已经生效。也不要仅为重现一篇诊断文章，就在活动机器上启停交换或调整容量。&lt;/p&gt;
&lt;h2 id="快速验证"&gt;快速验证&lt;/h2&gt;
&lt;p&gt;在安装了 util-linux 和 procps 的 Linux 环境运行这些只读命令。检查只观察当前环境的三个采样间隔，不制造内存压力，也不更改内核设置。机器没有启用交换也是有效观察结果，并不是实验失败；它只是告诉你不能依靠这些交换设备缓解未来的页面回收需求：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;set&lt;/span&gt; -eu
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;swapon --show
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;free -h
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;vmstat -y &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;grep -E &lt;span class="s1"&gt;&amp;#39;^(pswpin|pswpout|pgmajfault) &amp;#39;&lt;/span&gt; /proc/vmstat
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;test&lt;/span&gt; -r /proc/pressure/memory&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; cat /proc/pressure/memory
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;else&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;%s\n&amp;#39;&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;memory PSI is unavailable in this environment&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;swapon --show&lt;/code&gt; 列出已经启用的交换区域，&lt;code&gt;free&lt;/code&gt; 则分别报告内存与交换总量。&lt;code&gt;vmstat -y&lt;/code&gt; 省去自开机以来的首份统计，因此输出的三行对应采样间隔。阅读显示单位，把换入换出与阻塞任务、CPU 时间一起比较。随后从 &lt;code&gt;/proc/vmstat&lt;/code&gt; 读取的累计计数是另一份快照，不能直接当成前面每行对应的每秒速率。&lt;/p&gt;
&lt;p&gt;如果环境提供内存 PSI，它报告因内存压力而停顿的时间。&lt;code&gt;some&lt;/code&gt; 和 &lt;code&gt;full&lt;/code&gt; 分别表示测量范围内至少部分任务停顿，以及所有非空闲任务同时停顿。短暂安静的样本不能排除之前发生过尖峰。容器可见性与控制组边界也很重要：宿主累计计数并不会自动说明某一个应用还能分配多少内存，分析必须匹配真正受限制的对象。&lt;/p&gt;
&lt;p&gt;这项检查验证的是观察路径及解释方法，没有测量存储性能、决定安全交换容量，也没有验证 OOM 恢复。保留时间戳，用代表性的事故窗口对照应用延迟与资源限制。如果证据表明工作集持续挤压内存，应减少需求或提供适当容量。调整回收策略时要有可撤销方案，并衡量实际服务效果，不能把交换使用量永远为零当成独立目标。&lt;/p&gt;
&lt;h2 id="来源"&gt;来源&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.kernel.org/admin-guide/sysctl/vm.html#swappiness"&gt;内核 VM sysctl&lt;/a&gt;，相对 I/O 成本与零值行为，已核验 2026-10-15。&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.kernel.org/filesystems/tmpfs.html"&gt;内核 tmpfs&lt;/a&gt;，可换出的 tmpfs 与挂载限制，已核验 2026-10-15。&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.kernel.org/admin-guide/blockdev/zram.html"&gt;内核 zram&lt;/a&gt;，压缩块设备与存储统计，已核验 2026-10-15。&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.kernel.org/admin-guide/mm/zswap.html"&gt;内核 zswap&lt;/a&gt;，压缩交换缓存及后备设备关系，已核验 2026-10-15。&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.kernel.org/accounting/psi.html"&gt;内核 PSI&lt;/a&gt;，内存停顿范围与平均值，已核验 2026-10-15。&lt;/li&gt;
&lt;li&gt;&lt;a href="https://man7.org/linux/man-pages/man8/vmstat.8.html"&gt;vmstat(8)&lt;/a&gt;，间隔报告与交换速率字段，已核验 2026-10-15。&lt;/li&gt;
&lt;li&gt;&lt;a href="https://man7.org/linux/man-pages/man5/proc_vmstat.5.html"&gt;proc_vmstat(5)&lt;/a&gt;，独立的交换与主缺页计数，已核验 2026-10-15。&lt;/li&gt;
&lt;li&gt;&lt;a href="https://man7.org/linux/man-pages/man8/swapon.8.html"&gt;swapon(8)&lt;/a&gt;，活动清单与交换文件约束，已核验 2026-10-15。&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item></channel></rss>