Linux内核内存压缩技术

来源:互联网 发布:淘宝满1000减50怎么用 编辑:程序博客网 时间:2024/06/05 02:00

为什么需要内存压缩

说到压缩这个词,我们都可以想到是降低占用空间,使同样的空间可以存放更多的东西,如我们平时常用的压缩文件等。内存压缩同样也是为了节省内存。
内存无论是多大,总是不够用的(至少目前如此),而当系统内存紧张的时候,系统会将匿名页swap出去disk(flash).而这涉及到IO操作,这RAM操作速度不是一个数量级的。因此,如果频繁地做IO操作,不仅影响flash使用寿命,还严重影响系统性能。
内存压缩是一种让IO过程平滑过渡的做法。

目前主流的内核压缩技术

ZSWAP

ZSWAP是在memory与disk(flash)之间的一层“cache”,当内存需要swap出去disk的时候,先通过压缩放到zswap中去,swap的空间按需增长。达到一定程度zswap写到flash中去。

这里写图片描述

ZRAM

使用内存模拟block dev的做法。实际不会写到块设备中去,只会压缩后写到模拟的块设备中,其实也就是还是在内存中,只是通过压缩了,但压缩和解压缩的速度远远比读写IO好。因此在嵌入式设备广泛使用。压缩算法常用LZ4(压缩率不高,但压缩和解压缩速度非常快,对性能影响小)。

这里写图片描述

ZCACHE

oracle提出的一种实现,也是memory与blk dev之间的一层“cache”,与zswap比较接近,但使用的内存分配方法不同。zswap使用zsmalloc,zcache使用zbud或z3fold。

内存压缩内存分配器

zbud

zbud是一个专门为存储压缩page而设计的内存分配器.用于将两个压缩的page存到一个单独的page中.zbud page 被分成chunks,每一个chunk的size是64byte
这里写图片描述

zsmalloc

在内核中,slab分配器用于分配较小块内存,它将多个相同大小的对象放在同一个内存页中,但这些对象可能不能正好占满整个内存页,从而产生碎片造成浪费,于是内核尝试为对象分配多个物理连续内存页从而使碎片尽可能小,但在低内存设备上要分配多个连续内存页可能十分困难,特别在系统运行较长时间后,这变得几乎不可能。最坏情况下,当对象大小略大于PAGE_SIZE/2时,每个内存页接近一般的内存将被浪费。
所以,我们需要一种新的分配器,用于像vmalloc那样分配只要求虚拟连续的内存块。
Zsmalloc分配器尝试将多个相同大小的对象存放在组合页(称为zspage)中,这个组合页不要求物理连续,从而提高内存的使用率。但是,使用zsmalloc分配器有以下条件:

  • 不要求物理内存连续
  • 在使用对象前必须显示映射
  • 对象必须在原子上下文中访问

  • 这里写图片描述

z3fold

新的内存分配器。

  • 压缩率更高(3x)

这里写图片描述

为什么zram不能用zbud?

这里写图片描述

这里写图片描述

这里写图片描述

统一内存分配接口zpool

zpool是一个统一的内存分配接口,使用者为zbud,zsmalloc,z3fold.

const char *zpool_get_type(struct zpool *zpool){    return zpool->driver->type;}int zpool_malloc(struct zpool *zpool, size_t size, gfp_t gfp,            unsigned long *handle){    return zpool->driver->malloc(zpool->pool, size, gfp, handle);}void zpool_free(struct zpool *zpool, unsigned long handle){    zpool->driver->free(zpool->pool, handle);}

参考资料

[1].刘勃:Linux内核中的内存压缩技术.pdf
[2].https://www.elinux.org/File:Z3fold.pdf
[3].LinuxConJapan2013-Kamezawa.pdf

原创粉丝点击