1. 技术背景

说到压缩这个词,我们并不陌生,应该都能想到是降低占用空间,使同样的空间可以存放更多的东西,类似于我们平时常用的文件压缩,内存压缩同样也是为了节省内存。

尽管当前android手机6GB,8GB甚至12GB的机器都较为常见了,但内存无论多大,总是会有不够用的时候。当系统内存紧张的时候,会将文件页丢弃或回写回磁盘(如果是脏页),还可能会触发LMK杀进程进行内存回收。这些被回收的内存如果再次使用都需要重新从磁盘读取,而这个过程涉及到较多的IO操作。就目前的技术而言,IO的速度远远慢于这RAM操作速度。因此,如果频繁地做IO操作,不仅影响flash使用寿命,还严重影响系统性能。内存压缩是一种让IO过程平滑过渡的做法, 即尽量减少由于内存紧张导致的IO,提升性能。

2. 主流内存压缩技术

目前linux内核主流的内存压缩技术主要有3种:zSwap, zRAM, zCache。

2.1 zSwap

zSwap是在memory与flash之间的一层“cache”,当内存需要swap出去磁盘的时候,先通过压缩放到zSwap中去,zSwap空间按需增长。达到一定程度后则会按照LRU的顺序(前提是使用的内存分配方法需要支持LRU)将就最旧的page解压写入磁盘swap device,之后将当前的page压缩写入zSwap。

zswap本身存在一些缺陷或问题:

  1. 如果开启当zswap满交换出backing store的功能, 由于需要将zswap里的内存按LRU顺序解压再swap out, 这就要求内存分配器支持LRU功能。
  2. 如果不开启当zswap满交换出backing store的功能, 和zRam是类似的。

2.2 zRram

zRram即压缩的内存, 使用内存模拟block device的做法。实际不会写到块设备中去,只会压缩后写到模拟的块设备中,其实也就是还是在RAM中,只是通过压缩了。由于压缩和解压缩的速度远比读写IO好,因此在移动终端设备广泛被应用。zRam是基于RAM的block device, 一般swap priority会比较高。只有当其满,系统才会考虑其他的swap devices。当然这个优先级用户可以配置。

zRram本身存在一些缺陷或问题:

  1. zRam大小是可灵活配置的, 那是不是配置越大越好呢? 如果不是,配置多大是最合适的呢?
  2. 使用zRam可能会在低内存场景由于频繁的内存压缩导致kswapd进程占CPU高, 怎样改善?
  3. 增大了zRam配置,对系统内存碎片是否有影响?

要利用好zRam功能, 并不是简单地配置了就OK了, 还需要对各种场景和问题都做好处理, 才能发挥最优的效果。

2.3 zCache

zCache是oracle提出的一种实现文件页压缩技术,也是memory与block dev之间的一层“cache”,与zswap比较接近,但zcache目前压缩的是文件页,而zSwap和zRAM压缩是匿名页。

zcache本身存在一些缺陷或问题:

  1. 有些文件页可能本身是压缩的内容, 这时可能无法再进行压缩了
  2. zCache目前无法使用zsmalloc, 如果使用zbud,压缩率较低
  3. 使用的zbud/z3fold分配的内存是不可移动的, 需要关注内存碎片问题

3. 内存压缩主流的内存分配器

3.2.1 Zsmalloc

zsmalloc是为ZRAM设计的一种内存分配器。内核已经有slub了, 为什么还需要zsmalloc内存分配器?这是由内存压缩的场景和特点决定的。zsmalloc内存分配器期望在低内存的场景也能很好地工作,事实上,当需要压缩内存进行zsmalloc内存分配时,内存一般都比较紧张且内存碎片都比较严重了。如果使用slub分配, 很可能由于高阶内存分配不到而失败。另外,slub也可能导致内存碎片浪费比较严重,最坏情况下,当对象大小略大于PAGE_SIZE/2时,每个内存页接近一般的内存将被浪费。

Android手机实测发现,anon pages的平均压缩比大约在1:3左右,所以compressed anon page size很多在1.2K左右。如果是Slub,为了分配大量1.2K的内存,可能内存浪费严重。zsmalloc分配器尝试将多个相同大小的对象存放在组合页(称为zspage)中,这个组合页不要求物理连续,从而提高内存的使用率。

需要注意的是, 当前zsmalloc不支持LRU功能, 旧版本内核分配的不可移动的页, 对内存碎片影响严重, 但最新版本内核已经是支持分配可移动类型内存了。

3.2.2 Zbud

zbud是一个专门为存储压缩page而设计的内存分配器。用于将2个objects存到1个单独的page中。zbud是可以支持LRU的, 但分配的内存是不可移动的。

3.2.3 Z3fold

z3fold是一个较新的内存分配器, 与zbud不同的是, 将3个objects存到1个单独的page中,也就是zbud内存利用率极限是1:2, z3fold极限是1:3。同样z3fold是可以支持LRU的, 但分配的内存是不可移动的。

4. 内存压缩技术与内存分配器组合对比分析

结合上面zSwap / zRam /zCache的介绍, 与zsmalloc/zbud/z3fold分别怎样组合最合适呢?

下面总结了一下, 具体原因可以看上面介绍的时候各类型的特点。

-

zsmalloc

zbud

z3fold

zSwap(有实际swap device)

×(不可用)

√(可用)

√(最佳)

zSwap(无实际swap device)

√(最佳)

√(可用)

√(可用)

zRam

√(最佳)

√(可用)

√(可用)

zCache

×(不可用)

√(可用)

√(最佳)

5. zRAM技术原理

本文重点介绍zRam内存压缩技术,它是目前移动终端广泛使用的内存压缩技术。

5.1 软件框架

下图展示了内存管理大体的框架, 内存压缩技术处于内存回收memory reclaim部分中。

再具体到zRam, 它的软件架构可以分为3部分, 分别是数据流操作,内存压缩算法 ,zram驱动。

数据流操作:提供串行或者并行的压缩和解压操作。

内存压缩算法:每种压缩算法提供压缩和解压缩的具体实现回调接口供数据操作调用。

Zram驱动:创建一个基于ram的块设备, 并提供IO请求处理接口。

5.2 实现原理

Zram内存压缩技术本质上就是以时间换空间。通过CPU压缩、解压缩的开销换取更大的可用内存空间。

我们主要描述清楚下面这2个问题:

1) 什么时候会进行内存压缩?

2) 进行内存压缩/解压缩的流程是怎样的?

进行内存压缩的时机:

1) Kswapd场景:kswapd是内核内存回收线程, 当内存watermark低于low水线时会被唤醒工作, 其到内存watermark不小于high水线。

2) Direct reclaim场景:内存分配过程进入slowpath, 进行直接行内存回收。

下面是基于4.4内核理出的内存压缩、解压缩流程。

内存回收过程路径进行内存压缩。会将非活跃链表的页进行shrink, 如果是匿名页会进行pageout, 由此进行内存压缩存放到ZRAM中, 调用路径如下:

5.3 内存压缩算法

目前比较主流的内存算法主要为LZ0, LZ4, ZSTD等。下面截取了几种算法在x86机器上的表现。各算法有各自特点, 有以压缩率高的, 有压缩/解压快的等, 具体要结合需求场景选择使用。

6. zRAM技术应用

本节描述一下在使用ZRAM常遇到的一些使用或配置,调试的方法。

6.1 如何配置开启zRAM

1) 配置内存压缩算法

下面例子配置压缩算法为lz4

echo lz4 > /sys/block/zram0/comp_algorithm

2) 配置ZRAM大小

下面例子配置zram大小为2GB

echo 2147483648 > /sys/block/zram0/disksize

3) 使能zram

mkswap /dev/zram0

swapon /dev/zram0

6.2 swappiness含义简述

swappiness参数是内核倾向于回收匿名页到swap(使用的ZRAM就是swap设备)的积极程度, 原生内核范围是0~100, 参数值越大, 表示回收匿名页到swap的比例就越大。如果配置为0, 表示仅回收文件页,不回收匿名页。默认值为60。可以通过节点“/proc/sys/vm/swappiness”配置。

6.3 zRam相关的技术指标

1) ZRAM大小及剩余空间

Proc/meminfo中可以查看相关信息

SwapTotal:swap总大小, 如果配置为ZRAM, 这里就是ZRAM总大小

SwapFree:swap剩余大小, 如果配置为ZRAM, 这里就是ZRAM剩余大小

当然, 节点 /sys/block/zram0/disksize是最直接的。

2) ZRAM压缩率

/sys/block/zram/mm_stat中有压缩前后的大小数据, 由此可以计算出实际的压缩率

orig_data_size:压缩前数据大小, 单位为bytes

compr_data_size :压缩后数据大小, 单位为bytes

3) 换出/换入swap区的总量, proc/vmstat中中有相关信息

pswpin:换入总量, 单位为page

pswout:换出总量, 单位为page

6.4 zRam相关优化

上面提到zRam的一些缺陷, 怎么去改善呢?

  1. zRam大小是可灵活配置的, 那是不是配置越大越好呢? 如果不是配置多大是最合适的呢?

zRam大小的配置比较灵活, 如果zRam配置过大, 后台缓存了应用过多, 这也是有可能会影响前台应用使用的流畅度。另外, zRam配置越大, 也需要关注系统的内存碎片化情。因此zRam并不是配置越大越好,具体的大小需要根据内存总大小及系统负载情况考虑及实测而定。

  1. 使用zRam,可能会存在低内存场景由于频繁的内存压缩导致kswapd进程占CPU高, 怎样改善?

zRam本质就是以时间换空间, 在低内存的情况下, 肯定会比较频繁地回收内存, 这时kswapd进程是比较活跃的, 再加上通过压缩内存, 会更加消耗CPU资源。 改善这种情况方法也比较多, 比如, 可以使用更优的压缩算法, 区别使用场景, 后台不影响用户使用的场景异步进行深度内存压缩, 与用户体验相关的场景同步适当减少内存压缩, 通过增加文件页的回收比例加快内存回收等等。

  1. 增大了zRam配置,对系统内存碎片是否有影响?

使用zRam是有可能导致系统内存碎片变得更严重的, 特别是zsmalloc分配不支持可移动内存类型的时候。新版的内核zsmalloc已经支持可移动类型分配的, 但由于增大了zRam,结合android手机的使用特点, 仍然会有可能导致系统内存碎片较严重的情况,因些内存碎片问题也是需要重点关注的。解决系统内存碎片的方法也比较多, 可以结合具体的原因及场景进行优化。

zRAM内存压缩技术原理与应用相关推荐

  1. zRAM内存压缩技术分析及优化方向

    目录 1. zRAM出现的背景 2. zRAM软件架构 3. zRAM实现分析 3.1 zRAM驱动模块 3.2 数据流模块 3.3 压缩算法模块 3.4 zRAM读写流程 3.5 zRAM writ ...

  2. android zram内存压缩的优缺点

    内存不足时: Linux本身的做法是把程序不用的page交换到磁盘中去,并不是所有的page会被映视到物理内存,现代计算机为何用page管理内存,可以参考操作系统书籍 linux加入一个新的方案zra ...

  3. 剩余 大小 查看内存_谈谈内存压缩那些事

     1. 技术背景 说到压缩这个词,我们并不陌生,应该都能想到是降低占用空间,使同样的空间可以存放更多的东西,类似于我们平时常用的文件压缩,内存压缩同样也是为了节省内存. 尽管当前android手机6G ...

  4. 内存压缩是什么?有什么用?

    知识重点:请问...和那个内存清理有什么不同?回答列表1 内存压缩技术介绍为节省存储空间或传输带宽,人们已经在计算机系统中广泛地使用了数据压缩技术.在磁介质存储数据或网络传输数据时,人们使用基于硬.. ...

  5. 计算机处理io和cpu,虚拟化技术原理(CPU、内存、IO)

    虚拟化 云计算现在已经非常成熟了,而虚拟化是构建云计算基础架构不可或缺的关键技术之一. 云计算的云端系统, 其实质上就是一个大型的分布式系统. 虚拟化通过在一个物理平台上虚拟出更多的虚拟平台, 而其中 ...

  6. Linux内存从0到1学习笔记(11.2 内存优化方案之内存压缩zram)

    写在前面 zram是Linux内核提供的一种虚拟内存压缩功能,通过在将一部分内存模拟成块设备,并将压缩后的内存写到这部分模拟的块设备中,直到必须使用硬盘上的交换空间,zram 本质是就是一个块设备. ...

  7. 小米6内存测试软件,小米6有救了?MIUI测试内存扩展技术,原理是什么?

    原标题:小米6有救了?MIUI测试内存扩展技术,原理是什么? 由于Android底层运行机制原因,长时间使用后会导致卡顿现象,主流APP的身材愈发"臃肿"更令卡顿雪上加霜,多开几个 ...

  8. 【AI不惑境】模型压缩中知识蒸馏技术原理及其发展现状和展望

    大家好,这是专栏<AI不惑境>的第十一篇文章,讲述知识蒸馏相关的内容. 进入到不惑境界,就是向高手迈进的开始了,在这个境界需要自己独立思考.如果说学习是一个从模仿,到追随,到创造的过程,那 ...

  9. java内存池实现_Netty精粹之轻量级内存池技术实现原理与应用

    在Netty中,通常会有多个IO线程独立工作,基于NioEventLoop的实现,每个IO线程负责轮询单独的Selector实例来检索IO事件,当IO事件来临的时候,IO线程开始处理IO事件.最常见的 ...

最新文章

  1. aac文件损坏修复软件_SysTools Outlook Recovery Tool : 修复损坏的Outlook PST文件的先进的软件...
  2. 解决log4net独占日志文件的问题以及 log4net的各种输出配置(Appender)
  3. offSet().left 与position().left的区别
  4. Mybatis核心配置文件xml详解
  5. 读保护_混合ASIL系统中不同安全等级模块间的边界保护
  6. Spring Boot war方式打包发布
  7. JAVA设计模式有意思的国外站点
  8. 16篇最新推荐系统论文送你(文末附打包下载链接)
  9. oracle 表字段顺序_如何更改Oracle数据库表中字段顺序
  10. mysql sha1prng_为啥POST过来的
  11. PIX防火墙基本特性:失效处理机制和冗余-原理与实验
  12. javascript高级编程笔记04(基本概念)
  13. Kafka安装包下载地址
  14. pe分区助手读不到Linux硬盘,解决WINPE下不显示硬盘的方法
  15. ma系列之-17-磁盘和文件系统1
  16. Java编程:将具有父子关系的数据库表数据转换为树形结构,支持无限层级
  17. 3Q大战多年后,互联网圈再没有仗义执言的优秀屌丝了
  18. c语言中对float保留固定3位,float保留三位小数 float,double 除法 保留 指定位
  19. 防护器件-ESD管知识普及
  20. iOS 手机淘宝 自动创建一个人的群聊 实现源码 hook 代码源码

热门文章

  1. 魂斗罗 归来 个人攻略经验总结
  2. java毕业设计电影网站系统设计Mybatis+系统+数据库+调试部署
  3. Git入门第一讲:Windows版本git下载安装
  4. uniapp 获取 iphone x 底部黑线高度_你从iPhone换回安卓的感受是怎样的呢?
  5. 【python】字典常用方法
  6. Django项目开发:图书后台管理系统
  7. 成长一夏 挑战赛来袭 专属社区福利来袭~免费获得CSDN定制T恤衫
  8. 利用MAPI实现电子邮件功能
  9. 2008系统服务器定时重启,windows 2008服务器定时重启
  10. 421. Maximum XOR of Two Numbers in an Array