zram 简介
2016-07-13 17:57
375 查看
本文部分转载于: http://kernel.meizu.com/zram-introduction.html
即使 RAM 的价格相对较低,zram 仍有利于嵌入式设备、上网本和其它相似的低端硬件设备。这些设备通常使用固态存储,它们由于其固有性质而寿命有限,因而避免以其提供交换空间可防止其迅速磨损。此外,使用 zRAM 还可显著降低 Linux 系统用于交换的 I/O 。
zram 在 2009 年的时候就进了 kernel 的 staging 目录,并于 2014 年 3 月 30 日发布的 3.14 版本正式合并入 Linux 内核主线。在 2014 年 6 月 8 日发布的 3.15 版本的 Linux 内核中,zram 已可支持 LZ4 压缩算法,而 LZO 仍然作为默认的压缩后端。内核 3.15 中的修改还改进了性能,以及经由 sysfs 切换压缩算法的能力。
Lubuntu 于 13.10 开始使用 zram 。截至 2012 年 12 月,Ubuntu 考虑为小内存的计算机默认启用 zram 。 Google 在 Chrome OS 中使用 zram,它也成为了 Android 4.4 及以后版本设备的一个选项。
本文主要介绍在 Android 设备上使用的 zram swap,它可以让小内存的设备在多任务的情况下切换自如,提高用户体验。
zram swap 主要原理就是从内存分配一块区域出来用作 swap 分区,每次如果内存空间不够了,不是把应用程序杀掉,而是把应用程序所占用的内存数据复制到 swap 分区,等切换回来的时候就可以直接把这部分数据恢复到内存当中,节省重新开启所需的时间。而被放到 swap 分区的应用程序,所占用的内存都是被压缩过的,比如,微信在普通内存中占用 50 MB 的空间,如果压缩率为 0.4,则放到 swap 分区里面的数据只需要 20 MB 的空间,这样 swap 分区里面就可以存放更多后台临时不用的应用程序,变相扩展了内存的大小。
Device Drivers -> Staging drivers (STAGING [=y])
3.15 及之后版本的 kernel
Device Drivers -> [*] Block devices -> Compressed RAM block device support
具体的配置项如下:
如果是直接将 zram 编译到内核,那只能在代码里面直接修改 num_devices,3.15 之前的版本代码路径是 drivers/staging/zram/zram_drv.c,3.15 及之后的版本代码路径是 ./drivers/block/zram/zram_drv.c ,默认 zram 设备个数是一个。
查看压缩流的最大个数,默认是 1
设定压缩流的最大个数
修改压缩算法
可以使用数值直接设置内存大小,单位是 bytes
也可以使用带内存单位作为后缀的方式设置内存大小
如果直接设置新的大小,就会提示设置失败,设备正在使用。所以先需要关闭设备。
可以发现zram0已经不属于交换分区了。接着继续设置大小
于是发现还是设置失败,设备正在使用。查看zram的驱动。
可以发现init_done条件不成立,查看init_done函数。
所以想要重新设置大小,在驱动中查看zram->meta在什么情况下为NULL
所以设置大小之前还需要执行reset操作。
zram 技术的由来
zram(也称为 zRAM,先前称为 compcache)是 Linux 内核的一项功能,可提供虚拟内存压缩。zram 通过在 RAM 内的压缩块设备上分页,直到必须使用硬盘上的交换空间,以避免在磁盘上进行分页,从而提高性能。由于 zram 可以用内存替代硬盘为系统提供交换空间的功能,zram 可以在需要交换 / 分页时让 Linux 更好利用 RAM ,在物理内存较少的旧电脑上尤其如此。即使 RAM 的价格相对较低,zram 仍有利于嵌入式设备、上网本和其它相似的低端硬件设备。这些设备通常使用固态存储,它们由于其固有性质而寿命有限,因而避免以其提供交换空间可防止其迅速磨损。此外,使用 zRAM 还可显著降低 Linux 系统用于交换的 I/O 。
zram 在 2009 年的时候就进了 kernel 的 staging 目录,并于 2014 年 3 月 30 日发布的 3.14 版本正式合并入 Linux 内核主线。在 2014 年 6 月 8 日发布的 3.15 版本的 Linux 内核中,zram 已可支持 LZ4 压缩算法,而 LZO 仍然作为默认的压缩后端。内核 3.15 中的修改还改进了性能,以及经由 sysfs 切换压缩算法的能力。
Lubuntu 于 13.10 开始使用 zram 。截至 2012 年 12 月,Ubuntu 考虑为小内存的计算机默认启用 zram 。 Google 在 Chrome OS 中使用 zram,它也成为了 Android 4.4 及以后版本设备的一个选项。
本文主要介绍在 Android 设备上使用的 zram swap,它可以让小内存的设备在多任务的情况下切换自如,提高用户体验。
zram swap 主要原理就是从内存分配一块区域出来用作 swap 分区,每次如果内存空间不够了,不是把应用程序杀掉,而是把应用程序所占用的内存数据复制到 swap 分区,等切换回来的时候就可以直接把这部分数据恢复到内存当中,节省重新开启所需的时间。而被放到 swap 分区的应用程序,所占用的内存都是被压缩过的,比如,微信在普通内存中占用 50 MB 的空间,如果压缩率为 0.4,则放到 swap 分区里面的数据只需要 20 MB 的空间,这样 swap 分区里面就可以存放更多后台临时不用的应用程序,变相扩展了内存的大小。
zram 配置步骤
3.15 之前版本的 kernelDevice Drivers -> Staging drivers (STAGING [=y])
3.15 及之后版本的 kernel
Device Drivers -> [*] Block devices -> Compressed RAM block device support
具体的配置项如下:
CONFIG_RESOURCE_COUNTERS=y CONFIG_MEMCG=y CONFIG_MEMCG_SWAP=y CONFIG_MEMCG_SWAP_ENABLED=y CONFIG_MEMCG_KMEM=y CONFIG_ZRAM=y CONFIG_TOI_ZRAM_SUPPORT=y CONFIG_ZRAM_DEBUG=y
zram 块设备个数设定
如果是将 zram 编译成模块,则可以使用下面命令动态加载,这个命令会创建 4 个设备 /dev/zram{0,1,2,3}modprobe zram num_devices=4
如果是直接将 zram 编译到内核,那只能在代码里面直接修改 num_devices,3.15 之前的版本代码路径是 drivers/staging/zram/zram_drv.c,3.15 及之后的版本代码路径是 ./drivers/block/zram/zram_drv.c ,默认 zram 设备个数是一个。
压缩流的最大个数设定
这个是 3.15 版本及以后的 kernel 新加入的功能,3.15 版本之前的 zram 压缩都是使用一个压缩流(缓存 buffer 和算法私有部分)实现,每个写(压缩)操作都会独享压缩流,但是单压缩流如果出现数据奔溃或者卡住的现象,所有的写(压缩)操作将一直处于等待状态,这样效率非常低;而多压缩流的架构会让写(压缩)操作可以并行去执行,大大提高了压缩的效率和稳定性查看压缩流的最大个数,默认是 1
cat /sys/block/zram0/max_comp_streams
设定压缩流的最大个数
echo 3 > /sys/block/zram0/max_comp_streams
压缩算法选择
查看目前支持的压缩算法cat /sys/block/zram0/comp_algorithm lzo [lz4]
修改压缩算法
echo lzo > /sys/block/zram0/comp_algorithm
zram 内存大小设定
分配部分内存作为 zram ,大小建议为总内存的 10%-25%可以使用数值直接设置内存大小,单位是 bytes
echo $((512*1024*1024)) > /sys/block/zram0/disksize
也可以使用带内存单位作为后缀的方式设置内存大小
echo 256K > /sys/block/zram0/disksize echo 512M > /sys/block/zram0/disksize echo 1G > /sys/block/zram0/disksize
启用 zram 设备为 swap
mkswap /dev/zram0 swapon /dev/zram0
具体的 zram 相关对外接口说明
Name Access Description disksize RW 显示和设置该块设备的内存大小 initstate RO 显示设备的初始化状态 reset WO 重置设备 num_reads RO 读数据的个数 failed_reads RO 读数据失败的个数 num_write RO 写数据的个数 failed_writes RO 写数据失败的个数 invalid_io RO 非页面大小对齐的I/O请求的个数 max_comp_streams RW 最大可能同时执行压缩操作的个数 comp_algorithm RW 显示和设置压缩算法 notify_free RO 空闲内存的通知个数 zero_pages RO 写入该块设备的全为的页面的个数 orig_data_size RO 保存在该块设备中没有被压缩的数据的大小 compr_data_size RO 保存在该块设备中已被压缩的数据的大小 mem_used_total RO 分配给该块设备的总内存大小 mem_used_max RW 该块设备已用的内存大小,可以写 1 重置这个计数参数到当前真实的统计值 mem_limit RW zram 可以用来保存压缩数据的最大内存 pages_compacted RO 在压缩过程中可用的空闲页面的个数 compact WO 触发内存压缩
reset zram
reset zram后,zram的大小就会变为0,在使用之前必须需要设置大小echo 1 > /sys/block/zram0/reset
改变zram的大小
如果zram的大小比较小,不能满足需要。需要就该zram的大小。root@test:/data # echo $((512*1024*1024)) > /sys/block/zram0/disksize sh: echo: write error: Device or resource busy
如果直接设置新的大小,就会提示设置失败,设备正在使用。所以先需要关闭设备。
root@test:/data # cat /proc/swaps Filename Type Size Used Priority /dev/zram0 partition 409596 4456 -1 root@test:/data # swapoff /dev/zram0 root@test:/data # cat /proc/swaps Filename Type Size Used Priority root@test:/data #
可以发现zram0已经不属于交换分区了。接着继续设置大小
root@test:/data # echo $((512*1024*1024)) > /sys/block/zram0/disksize sh: echo: write error: Device or resource busy root@test:/data #
于是发现还是设置失败,设备正在使用。查看zram的驱动。
static ssize_t disksize_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { .... if (init_done(zram)) { pr_info("Cannot change disksize for initialized device\n"); err = -EBUSY; goto out_destroy_comp; } }
可以发现init_done条件不成立,查看init_done函数。
static inline int init_done(struct zram *zram) { return zram->meta != NULL; }
所以想要重新设置大小,在驱动中查看zram->meta在什么情况下为NULL
static void zram_reset_device(struct zram *zram, bool reset_capacity) { .... zram_meta_free(zram->meta); zram->meta = NULL; /* Reset stats */ memset(&zram->stats, 0, sizeof(zram->stats)); zram->disksize = 0; if (reset_capacity) set_capacity(zram->disk, 0); }
所以设置大小之前还需要执行reset操作。
root@test:/data # echo 1 > /sys/block/zram0/reset root@test:/data # echo $((512*1024*1024)) > /sys/block/zram0/disksize root@test:/data #
相关文章推荐
- IE7降低内存和降低CPU的几个技巧
- 如何高效的使用内存
- DOS下内存的配置
- XP/win2003下发现1G的内存比512M还慢的解决方法
- PowerShell实现动态获取当前脚本运行时消耗的内存
- C#实现把dgv里的数据完整的复制到一张内存表的方法
- SQL语句实现查询SQL Server内存使用状况
- C语言内存对齐实例详解
- 深入学习C语言中memset()函数的用法
- 全局变量与局部变量在内存中的区别详细解析
- VB读取线程、句柄及写入内存的API代码实例
- php运行提示:Fatal error Allowed memory size内存不足的解决方法
- IE浏览器IFrame对象内存不释放问题解决方法
- C#之CLR内存深入分析
- JavaScript 变量、作用域及内存
- JavaScript避免内存泄露及内存管理技巧
- J2ME编程中的几个重要概念介绍
- c++实现逐行读取配置文件写入内存的示例
- Shell脚本查看进程内存真实占用情况
- w3wp.exe占用cpu过高的解决方法第1/2页