匿名页:没有文件背景的页面,如:堆栈数据段
文件页的回收:将文件页回收到相应的磁盘上
匿名页的回收:在磁盘上划分额外分区,磁盘设备作为交换设备,交换设备必须是块设备。
swap机制:在内存不够用时,将部分内存上的数据交换到swap空间上,以便让系统不会因内存不够而导致OOM或更致命的情况。
内存回收的两种情况:
- 内核设计一个周期性回收内存的机制,不至于让系统的剩余内存长期处于很少的状态。
- 有大于空闲内存的申请到来时,触发强制内存回收。
针对两种不同的回收,分别实现两种不同的机制
- 用kswapd进程对内存周期性检查。
- 直接内存回收,当内存分配时没有空闲内存可以满足要求,触发直接回收,direct reclaim。
这两种内存回收的触发路径不同:
- 一个是由内核进程kswapd直接调用内存回收的逻辑进行内存回收;参见mm/vmscan.c中的kswapd()主逻辑
- 另一个是内存申请的时候进入slow
path的内存申请逻辑进行回收。参见内核代码中的mm/page_alloc.c中的__alloc_pages_slowpath方法
这两个方法中实际进行内存回收的过程殊途同归,最终都是 调用shrink_zone() 方法进行针对每个zone的内存页缩减。这个方法中会再调用shrink_lruvec()这个方法对每个组织页的链表进程检查。找到这个线索之后,我们就可以清晰的看到内存回收操作究竟针对的page有哪些了。这些链表主要定义在mm/vmscan.c一个enum中:根据这个enum可以看到,内存回收主要需要进行扫描的链表有如下4个:
- anon的inactive
- anon的active
- file的inactive
- file的active
就是说,内存回收操作主要针对的就是内存中的文件页(file cache)和匿名页。
kswapd何时执行swap操作
达到阈值时开始内存回收
Linux内核使用**水位标记(watermark)**的概念描述这个内存压力
共有三种水位:high,low,min
- 剩余内存在high以上表示剩余内存较多,压力不大
- high和low之间,表示存在一定压力
- low和min之间表示内存有较大压力,剩余内存不多
- 达到min说明内存面临很大压力
- 小于min这部分室内和保留给特定情况使用,一般不会分配
当系统剩余内存低于watermark[low]时,kswapd开始起作用,进行内存回收,直到剩余内存达到watermark[high]停止
当内存消耗导致剩余内存达到或者超过了watermark[min]时,会出发直接回收
watermark值的计算
- 根据当前内存总大小和一个可调参数进行运算,这个参数是/proc/sys/vm/min_free_kbytes
- 这个参数决定了系统每个zone的watermark[min]值的大小
内核根据min大小以及每个zone的内存大小分别计算每个zone的low和high大小
内存管理的相关逻辑都是以zone为单位的,zone的含义是内存的分区管理。
Linux将内存分成多个区,主要有
- DMA:直接访问区
- Normal:一般区
- HighMemory:高端内存区
交换空间:swap cache,提供page的查询功能,
从磁盘读取有文件背景的页面时,内核会分配一个page cache,缓存磁盘上的内容,相当于拷贝。
free命令可以查看当前page cache占用多少内存,free会打印出buffers和cached。
cached:通过文件系统访问文件(挂载文件系统,通过文件名打开)产生的缓存
buffers:直接访问裸盘,如cd /dev/sda设备去读写产生的缓存。
MMU:Memory Management Unit的缩写,中文名是内存管理单元,它是中央处理器(CPU)中用来管理虚拟存储器、物理存储器的控制线路,同时也负责虚拟地址映射为物理地址,以及提供硬件机制的内存访问授权,多用户多进程操作系统。
swappiness:是系统的一个参数,可以调节swap的使用优先级,决定了回收文件页和匿名页的优先级,swappiness越大,越倾向于回收匿名页,越小越倾向于回收文件页。
zRAM机制:从内存中拿出一段内存作为交换空间模拟硬盘的交换分区,用来交换匿名页,让kernel看到的物理内存不包括这段内存。这段交换空间自带压缩功能,交换到这段zRAM分区时,Linux会自动将匿名页压缩存放,系统访问这块页面内容时,Linux透明解压交换出来。
zram swap 主要原理就是从内存分配一块区域出来用作 swap 分区,每次如果内存空间不够了,不是把应用程序杀掉,而是把应用程序所占用的内存数据复制到 swap 分区,等切换回来的时候就可以直接把这部分数据恢复到内存当中,节省重新开启所需的时间。而被放到 swap 分区的应用程序,所占用的内存都是被压缩过的,比如,微信在普通内存中占用 50 MB 的空间,如果压缩率为 0.4,则放到 swap 分区里面的数据只需要 20 MB 的空间,这样 swap 分区里面就可以存放更多后台临时不用的应用程序,变相扩展了内存的大小。
zRAM好处:访问内存比访问硬盘速度快,这段内存是压缩后存储的,可以存储更多的数据,虽然占用一段内存,但实际可以存放更多。可以让小内存的设备在多任务的情况下切换自如,提高用户体验
ZARM SWAP 缺点:
如果在大内存的设备上使用,不仅不会快,反倒因为不断复制内存并且CPU反复压缩解压内从而拖慢速度。
举例说明
总内存:600M= 300M(SWAP) +300 (活动内存)
每个程序占用30M,压缩后是10M。
没有ZRAM SWAP 方案:
你可以同时打开 20 个程序 600/30 = 20
有ZRAM SWAP方案:
SWAP 里面可以保存 300/10 = 30
活动内存里可以运行 300/30 = 10
总共你可以同时运行 40 个程序, 这就是差别。