尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

zRAM内存压缩详解:Linux与Windows下的配置原理与优化实践

zRAM内存压缩详解:Linux与Windows下的配置原理与优化实践 先讲个我自己的经历。前两年我把一台只有4GB内存的旧笔记本翻出来当备用机系统装好后别的都挺好就是稍微多开几个网页就卡得不行风扇呼呼转系统还时不时把软件窗口弹出来说“内存不足”。后来我花了一个下午给这台机器配上了zRAM直接用内存压缩换空间效果立竿见影——同样的负载下卡顿少了很多Swap的读写次数也降下来了。从那以后我在Linux桌面、服务器甚至Windows上都会先看一眼内存压缩是否被正确利用了。这篇文章就把zRAM这套东西从头到尾聊透包括它到底是什么、在内核里怎么工作的、Linux和Android下怎么实操配置、参数怎么调以及很多人搜的“Windows 10/11内存压缩要不要关”这个问题。无论你是被低配机器折磨的普通用户还是想给生产服务器省点IO的运维都能从里面找到能直接用的方案。1. 先搞懂zRAM到底做了什么原理与设计思路1.1 内存压缩和虚拟内存有什么不一样先说个最基础的问题zRAM和传统Swap很多人以为是一回事其实机制完全不同。传统意义上的Swap是把内存里暂时不用的页面挪到磁盘上等要用的时候再读回来。这个过程最大的瓶颈就是磁盘IO——就算用的NVMe SSD它的随机读写延迟也是内存的几个数量级以上所以一旦系统频繁交换就会觉得卡。zRAM的思路是反过来的它不把数据搬到磁盘而是在内存里开辟一块区域作为压缩块设备把那些暂时不用的内存页面压缩之后存进去。你可以这样理解内存是一张书桌磁盘是外面的储物间。传统Swap是桌上放不下了就把东西搬去储物间来回取很费时间zRAM是在书桌下面塞了个压缩行李箱东西先折叠压缩塞进去既没有离开书桌范围又能腾出桌面空间代价是每次放取都要多花一点“折叠”和“展开”的时间。这个“折叠”就是CPU压缩对应的是压缩和解压操作“展开”就是缺页时从压缩区读回原始页面。所以zRAM是用CPU资源换取内存空间说白了就是把一部分计算力转换为可用内存。对于内存紧张、但又不想依赖磁盘交换的场景这个交换非常划算。1.2 zRAM在内核里的完整流转过程从Linux内核的角度看zRAM是一个基于RAM的块设备驱动。它通过内核的内存管理子系统注册成一个块设备通常叫/dev/zram0、/dev/zram1。你可以把它格式化并作为Swap分区使用但它实际上并没有真实磁盘在后面支撑写入的数据会被内核压缩算法处理后保存在RAM页面里。具体流程是这样的进程访问某块内存发现对应的页面被换出了触发缺页异常内核从zRAM设备读取压缩数据解压后放回物理内存。反过来当内存压力升高时会触发回收机制把匿名页面写入zRAM设备写入前先经过压缩算法例如LZ4或ZSTD压成一块更小的数据保存在内存中。从Swap子系统的视角看zRAM就是一个普通的交换设备但它没有真实块设备的延迟和磨损问题。这里要注意的是zRAM处理的页面主要是匿名页也就是进程堆栈这种没有磁盘文件对应的页面。文件页的回收通常是直接丢弃缓存、下次再从文件读不需要走Swap。所以你在/proc/meminfo里看到Swap占用上涨一般对应的是进程匿名页在内存压力下被压缩到了zRAM。1.3 为什么Android、Chromebook这些设备最早普及zRAMzRAM在2014年前后进入内核主线后来被Google大量用于Android系统到现在几乎成了低内存手机的标配。原因很现实手机的内存颗粒成本高、焊在主板上无法扩展而且老式手机用的是eMMC或UFS闪存频繁交换会加速闪存磨损。zRAM把换页数据留在内存里既缓解了内存不足又减少了闪存写入对设备寿命也有好处。桌面Linux反而没那么普及很多人还不知道自己发行版默认就能用zRAM。不过近几年Fedora、Ubuntu等发行版都开始在安装时或默认配置里包含zram-generator内存较小的云主机、树莓派这类设备上也越来越常见。Windows那边虽然路径不同但从Windows 10开始也有了类似的内存压缩机制这就是很多人搜“win10关闭内存压缩”以及“win11内存压缩要不要开”的由来。后面我会专门讲Windows的情况先继续把Linux/zRAM本身讲透。2. Linux和Android下从零启用zRAM配置实操与参数选择2.1 先检查当前环境有没有zRAM在动手配置之前先看看你的系统现状。现在很多发行版内核里已经编译了zram模块只是没有被启用。几个常用命令# 查看当前是否有zram设备以及大小/算法/使用量 zramctl # 看当前swap设备列表如果有类似 /dev/zram0 的条目说明已经在用 cat /proc/swaps # 确认内核模块是否可用这一行如果有输出说明模块存在 modinfo zram | head -20 # 查看zram设备目录是否存在 ls -l /sys/class/zram/如果你的系统里已经有zram0设备那可能是发行版默认启用了直接看zramctl输出就能了解大小和使用率。如果没有大概率需要手动加载模块并创建设备。在低版本内核或精简内核上可能连zram模块都没有那就需要重新编译内核或在BIOS/内核参数里开启不过这类情况很少见现在主流内核基本都带。2.2 手动创建并启用zRAM完整命令拆解如果你的系统没有默认启用zRAM可以按下面这套流程操作。需要root权限。我用的是2GB的zRAM设备算法LZ4具体大小和算法可以根据你的场景调整后面会讲怎么选。# 1. 加载zram模块 modprobe zram # 2. 找到新出现的zram设备 ls /sys/class/zram/ # 3. 指定压缩算法写入/sys/class/zram/zram0/comp_algorithm echo lz4 /sys/class/zram/zram0/comp_algorithm # 4. 设置设备大小这一步相当于“给压缩行李箱定容量” echo 2G /sys/class/zram/zram0/disksize # 5. 格式化成swap mkswap /dev/zram0 # 6. 开启swap并设置一个较高的优先级确保系统优先使用zRAM而不是磁盘swap swapon -p 100 /dev/zram0第4行特别重要disksize不是它实际占用的内存而是未压缩数据的最大容量。也就是说2GB的disksize在极限情况下可能需要占用大约2GB的物理内存来存放压缩后的数据而实际能容纳的原始数据可能远大于2GB取决于压缩率。这个“看似矛盾”的特性恰恰是zRAM大小的调优关键后面专门讲。第6行的-p 100给这个swap设备设置了100的优先级。Linux的swap优先级数值越大越优先使用所以设置高优先级可以确保系统先用zRAM再用磁盘swap如果你还保留了的话。不做这步的话如果机器上同时有磁盘swap分区内核可能雨露均沾zRAM的优势就发挥不出来。配置完成后可以验证一下cat /proc/swaps zramctl/proc/swaps里应该出现/dev/zram0的条目zramctl里会显示算法、大小、已使用量、压缩率等数据。2.3 开机自动启用systemd和zram-generator手动配置只能生效到重启前。想要开机自动启用最简单的方案是使用发行版自带的zram-generator这是目前Fedora、Ubuntu等系统上比较推荐的方案。安装zram-generator后在/etc/systemd/zram-generator.conf里写下类似配置[zram0] zram-size min(ram / 2, 4096) compression-algorithm lz4然后启用服务sudo systemctl daemon-reload sudo systemctl start systemd-zram-setupzram0.service sudo systemctl enable systemd-zram-setupzram0.servicezram-size里可以写min(ram / 2, 4096)这种表达式它表示取“内存的一半”和“4GB”中较小的那个。这个语法用起来很方便也避免在小内存机器上配出过大设备。还可以通过/etc/systemd/zram-generator.conf.d/目录下的覆盖文件按需调整。没有systemd的老系统或者你想完全手动控制也可以自己写一个systemd service或udev规则但这属于非主流路径我建议优先用zram-generator既简单又不容易出错。2.4 zRAM大小怎么定经验公式与参数计算这是新手问得最多的一个问题2GB内存开2GB zRAM好不好16GB内存要不要开8GB先说结论zRAM的大小没有一个绝对正确的值但有个接近最佳实践的范围物理内存的25%到50%一般取50%作为默认但别超过物理内存本身。为什么不能太大因为zRAM设备占用的物理内存是动态增长的。写进zRAM的数据会一直驻扎在内存里如果disksize设成8GB而实际内存才8GB那么当zRAM使用接近饱和时系统剩下的物理内存会非常少反而触发更严重的回收抖动甚至导致OOM。zRAM不是内存的免费增量它只是用CPU换来的“有效容量”。从另一个角度看zRAM设太小比如只有128MB效果又有限内存压力稍涨就溢出到磁盘swap。所以一个比较稳的公式4GB内存的机器zRAM 1GB到2GB8GB内存的机器zRAM 2GB到4GB16GB内存的机器zRAM 4GB已经足够没必要更大32GB以上内存说实话装不装zRAM影响都不明显但如果你跑了很多内存密集型的服务可以开4GB兜底手机厂商的做法可以作为参考很多Android手机上zRAM约等于物理内存的一半而且系统会在内存充足时尽量少写zRAM内存紧张时才加大使用。内核较新的版本里还能配合mem_sleep、writeback等机制把冷页逐渐写回磁盘做成“zRAMswap”的两级方案但这套机制在一般桌面上不太常用。2.5 压缩算法选型LZ4、ZSTD、LZO怎么选zRAM支持的压缩算法取决于内核编译选项和硬件常见的有LZ4、LZO、LZ4HC、ZSTD、DEFLATE等。不同的算法在压缩率和CPU开销上差异明显选错了会在低配设备上感受到卡顿。算法压缩率压缩速度解压速度CPU开销适用场景LZ4较低非常快非常快低低配CPU、内存极端紧张时推荐LZO / LZO-RLE较低快快低内核传统默认兼容性好ZSTD高中等快中等CPU有余量、需要更高压缩率时DEFLATE高慢中等高基本不推荐用于实时压缩路径我自己的经验是如果CPU是近几年主流的酷睿、锐龙、或者中端以上ARM芯片优先选ZSTD压缩率比LZ4高不少内存收益更明显CPU开销也在可接受范围内。如果是老旧的Atom、奔腾、树莓派一代或者你特别在意CPU占用选LZ4更稳。可以用一条命令快速切换算法后看zramctl里报告的压缩率不同工作负载差异很大实测比看评测表有用。在Android设备上很多厂商默认也用LZ4或LZ4-RLE因为手机对功耗和发热更敏感压缩算法的CPU开销不能太大。这点桌面用户也要记住zRAM本质上是拿CPU换内存算法选型就是在“换多少”和“花多少”之间找平衡。3. 别忽略这些参数swappiness、page_cluster与完整调优案例3.1 vm.swappiness到底该设多少跑通zRAM之后还要调内核参数才能真正发挥效果。最容易被忽视的就是vm.swappiness。很多人印象里swappiness越大内存越容易被换出越小越倾向保留内存这在传统磁盘swap场景下基本正确。但在zRAM场景下这个参数的意义变成系统倾向于用多少“压缩内存”来替代“物理内存”和“文件缓存”。zRAM的读写比磁盘快得多所以可以更放心地提高swappiness。不过这里有个经验问题在桌面Linux上如果内存本来就够用你把swappiness调到100系统可能过度积极地把匿名页塞进zRAM反而导致CPU压缩开销变大操作界面偶尔会出现延迟。如果内存很紧张比如只有2GB或4GB那swappiness100反而能充分发挥zRAM优势。我的建议是内存小于等于4GB的机器vm.swappiness100内存8GB左右日常多开浏览器/IDEvm.swappiness80到100推荐100并观察一段时间内存16GB及以上vm.swappiness20到60都可以没必要激进设置方式sudo sysctl vm.swappiness100要持久化的话写到/etc/sysctl.d/99-zram.conf里vm.swappiness100 vm.page_cluster03.2 vm.page_cluster对zRAM的影响vm.page_cluster控制的是swap交换时一次读取的页面数量默认是3代表一次读2^38个页每个页4KB也就是32KB。在磁盘时代这是为了减少寻道次数而做的批量读取但在zRAM上数据就在内存里批量读反而可能读入很多当前用不上的页面浪费CPU解压时间。所以zRAM场景下建议把page_cluster设成0表示一次只读1个页。这个改动对低配CPU的效果非常明显能减少不少无谓解压。# 临时生效 echo 0 /proc/sys/vm/page_cluster # 持久化 # 写到 /etc/sysctl.d/99-zram.conf 即可3.3 一个8GB内存笔记本的完整调优案例分享一个我自己实际跑过的案例。机器是8GB内存的轻薄本CPU是AMD 4500U平时开Firefox加上二三十个标签页再用VS Code写代码偶尔起几个Node/Python进程。没配zRAM之前内存经常使用到90%以上系统开始往磁盘swap写入SSD读写在压力大的时候肉眼可见地飚高。我的配置是这样的zRAM大小4GB压缩算法ZSTDvm.swappiness100vm.page_cluster0启用后用zramctl看压缩数据占用的物理内存在800MB到1.5GB之间浮动但能容纳的原始数据量经常超过3GB。也就是说原本4GB的zRAM“行李箱”在ZSTD下能装下四五GB的原始内存页面实际节省的物理内存非常可观。再看不足Firefox切换标签页时偶尔会有微小的延迟任务管理器里zram0的IO也时不时跳动。这是因为页面在被回收后切回来需要解压属于正常开销。但相比之前按几下就卡死、SSD疯狂闪烁的情况这种体验已经好太多了。如果遇到切窗口偶尔卡顿的情况我会先把swappiness降低到80把page_cluster保持0通常能缓解。本质上就是在“更积极压缩内存”和“减少解压延迟”之间找一个自己的平衡点。3.4 Android上厂商是怎么调zRAM的Android系统的zRAM逻辑虽然基于同一个内核机制但走的是另一条调优路线。系统会根据内存压力动态调整zRAM的使用率而不只是一味地按固定比例换出。厂商通常会配合lmkd内存清理守护进程当内存快不够时先回收缓存、杀死低优先级进程再逐步加大zRAM的写入。这种策略比简单的swappiness更精细但主要面向手机整体功耗和流畅度平衡。普通Linux桌面上没有lmkd这类用户态协同所以需要靠内核参数手动模拟类似效果。对大多数桌面用户来说只要把zRAM开好、swappiness和page_cluster调好就已经比默认状态强太多了。没必要追求复刻手机的整套策略。4. Windows那边的内存压缩Win10/Win11要不要开怎么关4.1 Windows的Memory Compression是什么很多人搜“win10关闭内存压缩”“win11内存压缩要不要开”这里好好说一下。Windows从10代build 1507开始引入了内存压缩功能官方叫Memory Compression。它的位置在任务管理器“性能”页里的内存分类下你会看到一个“使用中(已压缩)”的指标。它的本质和zRAM非常像系统在内存不足时不再急着把页面写入磁盘上的页面文件pagefile而是先把页面压缩后保存在内存中。Windows把它绑定到一个系统进程上通常是“系统”或“内存压缩”进程。好处很明显压缩后能容纳更多页面又减少了对磁盘页面文件的写入。对于SSD寿命和响应速度都有帮助。这里要特别澄清一个误区Windows的“内存压缩”和“虚拟内存”是两个东西虚拟内存对应的是页面文件pagefile.sys压缩是额外的一层优化。就算你把虚拟内存关掉内存压缩仍然起作用反过来你禁用内存压缩页面文件照样可能被使用。所以网上的很多“关闭内存压缩关闭虚拟内存”的说法是错误的。4.2 如何查看Windows内存压缩状态想确认Win10/11当前是否启用了内存压缩最简单的办法是打开任务管理器切到“性能”标签点左侧的“内存”右侧能看到“使用中(已压缩)”的数值。如果这个数值一直是0KB说明可能被禁用了或者系统暂时没有触发压缩。更精确的方法是打开PowerShell执行Get-MMAgent看输出里MemoryCompression字段是True还是False。True代表启用状态。如果这一项是False且你想保守起见改回默认可以用下面这行命令重新开启Enable-MMAgent -MemoryCompression如果你确实想关闭可以用类似的命令但关之前一定要想清楚原因因为通常这个功能是帮你省内存而不是拖后腿的Disable-MMAgent -MemoryCompression Restart-Computer注意MMAgent全称是Memory Management Agent它管的不止内存压缩还包括SuperfetchSysMain部分的预读取行为。执行Get-MMAgent时还能看到ApplicationLaunchPrefetching、ApplicationPreLaunch等字段别把内存压缩和预读取混在一起操作。4.3 Win10/Win11内存压缩要不要关分场景建议这是热搜词里争议最大的一题。先说结论绝大多数情况下都不要关。内存压缩在你内存不足时能减少磁盘页面文件读写对整体流畅度和SSD寿命都是正收益。但这不代表它没有代价——压缩过程要吃CPU所以如果你用的是非常老的处理器比如上古赛扬、老Atom二合一设备内存压缩进程可能长期占用CPU造成界面卡顿。这种情况下关闭“内存压缩”不一定能解决卡顿因为内存不够时关闭压缩会导致更多数据写入页面文件磁盘IO又变高系统反而可能更卡。分场景建议16GB以上内存、平时负载不太高的用户开不开影响不大建议保留默认开启反正你也感知不到。8GB内存、普通办公/影音强烈建议开启。系统会在多开应用时把一些页面压进内存减少页面文件写入体验提升明显。4GB内存、低配CPU这个场景最特殊。内存压缩能救命但CPU太弱会拖慢解压速度。建议开启同时把虚拟内存页面文件保留在SSD上如果盘是HDD建议考虑换SSD说实话4GB内存的机器在2024年以后跑Win11本身就比较吃力。超大内存机器32GB以上且完全不关心内存占用关掉也不会有太大损失但也没有明显收益纯属折腾。如果你在“性能监视器”里看到“内存压缩”进程消耗了非常高比例的CPU而内存使用率一直不高这可能是某个驱动或软件和系统内存管理有兼容性问题先排查软件而不是急着关闭内存压缩。我自己遇到过一个情况某国产输入法的后台进程疯狂触发页面提交导致压缩进程CPU飙升换掉输入法后一切正常。4.4 Windows关闭内存压缩后可能遇到的典型后果有人确实因为特殊需求想关掉内存压缩那我就说说关掉后会发生什么。首先任务管理器里“使用中(已压缩)”会恒为0内存压力大时系统会更早、更多地使用页面文件。紧接着你会观察到SSD的写入量上升磁盘活动增加。如果你的SSD是低端款或HDD那系统在多任务场景下的响应速度大概率会变差甚至出现“明明内存没用完但程序切回来很慢”的情况因为页面文件读回来的延迟远大于压缩页面解压的延迟。另外一个隐藏影响是笔记本续航关闭内存压缩后内存压力大时频繁写磁盘SSD的功耗比压缩计算的功耗高不少续航可能会小幅下降。换句话说关闭内存压缩省下的CPU电量很可能从磁盘功耗上加倍还回去。所以我的建议很明确除非你非常明确地遇到了内存压缩进程异常占CPU的问题并且在排查后确认是内存压缩本身引起的否则保持Windows默认的开启状态就好。网上流传的“关闭内存压缩让游戏不卡”之类说法多半是混淆了卡顿原因。游戏卡顿更多来自GPU、后台进程、散热策略等因素内存压缩在大多数游戏场景下消耗极低不是主要瓶颈。5. 实测体验与常见问题排查实录5.1 常见问题速查表下面是这几年来我遇到的和朋友们常问的问题整理成一张表方便对照排查。问题现象可能原因解决办法swapon /dev/zram0报错“Invalid argument”没设置disksize就直接格式化/启用先echo 2G /sys/class/zram/zram0/disksize再mkswapmodprobe zram无输出但设备没出现内核没有编译zram模块检查/lib/modules/$(uname -r)是否存在zram相关内容或用发行版默认内核设置了优先级但系统还是用磁盘swap磁盘swap的优先级也高或zRAM优先级写入失败用swapon -p 100 /dev/zram0确保zRAM优先级最高查看cat /proc/swaps确认配置了zRAM后开机没有自动启用用了手动配置但没写自启服务用zram-generator或systemd service持久化配置zRAM使用率长期为0swappiness太低或内存压力不够检查sysctl值内存紧张时写入才会增加正常负载下没必要纠结zRAM占用的物理内存超过预期disksize设得过大或压缩数据本身较大用zramctl看实际压缩数据量调小disksize或考虑换更高压缩率算法压缩/解压导致CPU占用高选了高压缩率算法或CPU太弱换成LZ4降低zRAM大小或调低swappiness减少换页频率zramctl显示swap使用满数据量真的超过zRAM容量增加zRAM大小或保留少量磁盘swap作为兜底5.2 不同负载下zRAM的压缩率与内存收益参考压缩率是很多人关心的点。我这里说的“压缩率”指的是原始页面大小除以压缩后大小的比值。不同数据类型的压缩率差异极大不要指望所有场景都能达到2:1甚至3:1。负载类型典型压缩率说明文本编辑、网页渲染、代码编译2.5:1到4:1文本类数据冗余高压缩效果最好浏览器多标签复杂网页1.5:1到2.5:1混合了脚本、图片缓存但仍有不少文本视频渲染、图片处理1.1:1到1.5:1多媒体数据本身压缩率高再压收益低数据库/序列化对象1.2:1到2:1视字段类型而定全内存大负载多虚拟机1.5:1到2:1需要看虚拟机内部页面内容所以你配置4GB zRAM在文本和网页场景下可能实际扩出8GB到10GB的有效空间但如果你的负载全是视频/图片转码就别指望zRAM能带来明显收益。这也是为什么有些人反馈zRAM“没什么用”——负载类型决定了它的上限。5.3 几件值得记下来的避坑小事第一开了zRAM以后swap优先级一定不要和磁盘swap默认值一样。Linux默认swap优先级是负数比如-2但有些发行版会给swap分区设置更高的优先级。如果你用swapon /dev/zram0不带-p 100系统可能仍然优先用磁盘swap效果就大打折扣。第二不要把zRAM设备同时格式化成ext4等文件系统使用。虽然内核允许你把zRAM当成普通块设备做临时文件系统但这属于把压缩内存当RAM disk用内存开销会暴涨和“内存压缩”并不是一个概念。如果你看到有人推荐用zRAM做/tmp目录最好想清楚默认/tmp放tmpfs是更合适的选择。第三内核版本不同zRAM支持的算法和行为也有差异。老内核可能没有ZSTD有些版本的disksize只支持大端字节序的数值设置时最好用echo 2G这种写法而不是echo 2097152加单位混淆。建议先zramctl查看当前设备是否识别正常再继续操作。第四如果你在服务器上用zRAM要注意别把所有的swap都放在zRAM上最好保留一个小容量的磁盘swap分区作为极端情况下的兜底。因为zRAM占用的是内存万一内存中可用部分已经被zRAM占满系统连回收页面的空间都很难腾出来这时磁盘swap反而能防御OOM。这个策略在云主机上尤其重要。一些真实的小经验从刚开始觉得“内存压缩是骗人的”到后来真香我最大的体会是zRAM不是银弹它只是在“内存太小”和“磁盘太慢”这两个现实约束之间多给你一种软性的缓冲手段。对低配Linux机器、Android手机和Windows的8GB入门本来说开启内存压缩通常利大于弊但前提是配置要合理——别把disksize设成内存的好几倍也别指望所有负载都能压缩出惊喜。如果你现在手头正有一台吃紧的机器我的建议是先试着开一个等于内存一半大小的zRAM把算法选成LZ4或ZSTD然后把swappiness调到100、page_cluster设为0跑上两周看看实际体验。这套配置大概率比默认状态来得舒服。Windows那边不需要折腾关闭内存压缩默认设置对绝大多数人就是最优解。等技术慢慢迭代内存压缩这类省内存手段大概率会越来越普及早一点掌握它总没有坏处。
返回列表