将 zram 用于内存交换

2023-10-24 08:04
文章标签 用于 内存 交换 zram

本文主要是介绍将 zram 用于内存交换,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Linux 将物理内存分为内存段,叫做页面。交换(swap)是指内存页面被复制到预先设定好的硬盘空间(即交换空间)的过程,目的是释放这份内存页面。物理内存和交换空间的总大小是可用的虚拟内存的总量。交换空间可以是磁盘的一个分区,也可以是一个文件。用户可以在安装时或安装后的任何时候创建交换空间。交换空间有两种用途:一是将虚拟内存扩大到超过已安装的物理内存(RAM)的容量;二是用于 suspend-to-disk 支持。

使用 swap 扩展虚拟内存是否有好处取决于物理内存的使用情况。如果物理内存不足以支撑日常使用全部的程序的话(如日常使用时内存占满导致卡顿、死机),使用 swap 也许会有些帮助。这样可以避免 out of memory conditions —— Linux 内核 OOM Killer 机制将尝试通过杀进程的方式来自动释放内存。如果想让虚拟内存足够使用,就需要添加相应的差值(或更多)作为交换空间。

由此可见,对于一些小内存设备,使用 swap 是较为必要的,可以扩展内存,避免一些内存不足导致程序停止甚至无法启动的情况。

zram, 旧称为 compcache,是一个用于在内存中创建压缩的块设备的 Linux 内核模块,即带实时磁盘压缩的内存盘。通过 zram 创建的块设备可以用作 swap 或是内存盘。zram 有两个常见的应用场景,一个是储存临时文件(/tmp),另一个是用作 swap。早期 zram 只有前一个功能,也是它原名 “compcache” (compressed cache) 的由来。

说到这里不得不提一下 zwsap。zswap 是一个内核功能,它为交换页提供了一个压缩的内存缓存。原本会交换到磁盘的页被压缩并存储到内存中的存储池中。一旦池已满或内存耗尽,最近最少使用的(LRU)页就会被解压缩并写入磁盘,就好像它没有被拦截一样。将页解压缩到交换缓存后,可以释放池中的压缩版本。与 zram 相比的区别在于,zswap 与 swap 设备协同工作,而 zram 是内存中的交换设备,不需要后备交换设备。

将 zram 这种内存压缩技术用于 swap,可以避免与磁盘这种速度较慢设备的进行 I/O,用富裕的计算性能,换取 swap 所需的磁盘空间,更好地利用物理内存自身;而在固态硬盘普及的今天,这么做也可以避免开启 swap 后对磁盘的读写。

创建出的 zram 块设备最开始并不会预留或使用任何内存。仅当有文件需要被或者想要被交换出内存时,它们才会被压缩并移入 zram 块设备。因此,zram 块设备将会根据需要动态地增长或收缩。

例如,考虑一个具备 32 GiB 内存的系统,其上配置了容量为 64 GiB 的 zram。假设 zstd 能够实现 1:4 的压缩比率,当被全部占用时,该 zram 块被压缩后在物理内存中占用的大小将在 16 GiB 左右。下面用具体例子来向读者说明使用 zram 能在原本可用内存上带来的提升:

  • 当内存和 zram 均完全被占用时:16 GiB 内存 + 64 GiB zram (在内存中约占用 16 GiB)
  • 正常使用且未发生交换时:32 GiB 内存 + 0 GiB zram
  • 正常使用且发生少数交换时:30 GiB 内存 + 8 GiB zram (在内存中约占用 2 GiB)
  • 不进行任何 zram 配置:32 GiB 内存

可见,zram 总是提供能在内存中存储更多内容的优势。

不过需要注意:

  • 假如相关的 zswap 内核功能为启用状态,它将阻碍 zram 的有效使用。这是因为 zswap 会在 zram 之前被用作 swap 缓存,并在换出的内存分页到达 zram 前对其进行拦截和压缩。在这种情况下,大多数的 zram 其实并未被使用,尽管 zramctl(8) 的输出可能并非如此。
  • 如上所述,在配置 zram 时,zram 设备的大小控制着其能存储的最大未压缩数据量,而非最大压缩后数据量。可将 zram 的大小配置为与您系统的物理内存容量相等,甚至更大,只需保证数据压缩后所占用的大小不超过系统物理内存的容量即可。
  • 不支持在休眠时将内存换出至 zram,即便 zram 被配置在位于永久性存储的设备上。logind 会阻止休眠到配置在 zram 上的交换空间的尝试。

要启用 zram 并将其用于 swap 其实很简单。这里只介绍使用 systemd-zram-generator 的方式,其余详情请参见 zram 在 Arch Linux Wiki 上对应的页面。

开始之前,先确保禁用 zswap,方法这里不再赘述。

在 Debian 系发行版上通过 apt 安装 systemd-zram-generator

apt install systemd-zram-generator

 之后查阅并修改 /etc/systemd/zram-generator.conf 这个配置文件:

[zram0]
compression-algorithm = zstd
zram-size = ram / 2
swap-priority = 100

这里创建了一个使用 zstd 压缩、大小为所有可用内存容量一半的 zram swap 设备(ram / 2 表示大小为 RAM 大小的 1 / 2;也可以设置为 G 、512M 这样的值)。

之后应用修改并启动即可。

systemctl daemon-reload
systemctl start systemd-zram-setup@zram0

可使用 zramctl(8) 命令,或是通过查阅 systemd-zram-setup@zramN.service (等) 实例的 单元状态,来检查所配置的 /dev/zramN 设备的 swap 状态。zramctl 命令的输出以及内容的解释大致如下:

NAME       ALGORITHM DISKSIZE  DATA  COMPR  TOTAL STREAMS MOUNTPOINT
/dev/zram0 zstd           32G  1.9G 318.6M 424.9M      16 [SWAP]
  • DISKSIZE = 32G: 该 zram 设备最多会存储 32G 的未压缩数据
  • DATA = 1.9G: 目前, 该 zram 设备上存储着 1.9G (未被压缩的) 数据
  • COMPR = 318.6M: 这 1.9G 未被压缩的数据被压缩到了 318.6M
  • TOTAL = 424.9M: 包含元信息在内,这 1.9G 未压缩的数据使用了 424.9M 的物理内存

总之,使用 zram,可以用富余的运算资源,换取内存的高效利用,同时避免换出到磁盘时,对磁盘的过多写入。

这篇关于将 zram 用于内存交换的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/273827

相关文章

在Spring Boot中浅尝内存泄漏的实战记录

《在SpringBoot中浅尝内存泄漏的实战记录》本文给大家分享在SpringBoot中浅尝内存泄漏的实战记录,结合实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 目录使用静态集合持有对象引用,阻止GC回收关键点:可执行代码:验证:1,运行程序(启动时添加JVM参数限制堆大小):2,访问 htt

Python如何使用__slots__实现节省内存和性能优化

《Python如何使用__slots__实现节省内存和性能优化》你有想过,一个小小的__slots__能让你的Python类内存消耗直接减半吗,没错,今天咱们要聊的就是这个让人眼前一亮的技巧,感兴趣的... 目录背景:内存吃得满满的类__slots__:你的内存管理小助手举个大概的例子:看看效果如何?1.

C语言实现两个变量值交换的三种方式

《C语言实现两个变量值交换的三种方式》两个变量值的交换是编程中最常见的问题之一,以下将介绍三种变量的交换方式,其中第一种方式是最常用也是最实用的,后两种方式一般只在特殊限制下使用,需要的朋友可以参考下... 目录1.使用临时变量(推荐)2.相加和相减的方式(值较大时可能丢失数据)3.按位异或运算1.使用临时

使用C语言实现交换整数的奇数位和偶数位

《使用C语言实现交换整数的奇数位和偶数位》在C语言中,要交换一个整数的二进制位中的奇数位和偶数位,重点需要理解位操作,当我们谈论二进制位的奇数位和偶数位时,我们是指从右到左数的位置,本文给大家介绍了使... 目录一、问题描述二、解决思路三、函数实现四、宏实现五、总结一、问题描述使用C语言代码实现:将一个整

Redis 内存淘汰策略深度解析(最新推荐)

《Redis内存淘汰策略深度解析(最新推荐)》本文详细探讨了Redis的内存淘汰策略、实现原理、适用场景及最佳实践,介绍了八种内存淘汰策略,包括noeviction、LRU、LFU、TTL、Rand... 目录一、 内存淘汰策略概述二、内存淘汰策略详解2.1 ​noeviction(不淘汰)​2.2 ​LR

Golang基于内存的键值存储缓存库go-cache

《Golang基于内存的键值存储缓存库go-cache》go-cache是一个内存中的key:valuestore/cache库,适用于单机应用程序,本文主要介绍了Golang基于内存的键值存储缓存库... 目录文档安装方法示例1示例2使用注意点优点缺点go-cache 和 Redis 缓存对比1)功能特性

Go使用pprof进行CPU,内存和阻塞情况分析

《Go使用pprof进行CPU,内存和阻塞情况分析》Go语言提供了强大的pprof工具,用于分析CPU、内存、Goroutine阻塞等性能问题,帮助开发者优化程序,提高运行效率,下面我们就来深入了解下... 目录1. pprof 介绍2. 快速上手:启用 pprof3. CPU Profiling:分析 C

golang内存对齐的项目实践

《golang内存对齐的项目实践》本文主要介绍了golang内存对齐的项目实践,内存对齐不仅有助于提高内存访问效率,还确保了与硬件接口的兼容性,是Go语言编程中不可忽视的重要优化手段,下面就来介绍一下... 目录一、结构体中的字段顺序与内存对齐二、内存对齐的原理与规则三、调整结构体字段顺序优化内存对齐四、内

Linux内存泄露的原因排查和解决方案(内存管理方法)

《Linux内存泄露的原因排查和解决方案(内存管理方法)》文章主要介绍了运维团队在Linux处理LB服务内存暴涨、内存报警问题的过程,从发现问题、排查原因到制定解决方案,并从中学习了Linux内存管理... 目录一、问题二、排查过程三、解决方案四、内存管理方法1)linux内存寻址2)Linux分页机制3)

Java循环创建对象内存溢出的解决方法

《Java循环创建对象内存溢出的解决方法》在Java中,如果在循环中不当地创建大量对象而不及时释放内存,很容易导致内存溢出(OutOfMemoryError),所以本文给大家介绍了Java循环创建对象... 目录问题1. 解决方案2. 示例代码2.1 原始版本(可能导致内存溢出)2.2 修改后的版本问题在