1. page cache
Linux读写文件过程;
read:用户进程调用read命令,内核查询读取的文件内容是否在内存(内核page
cache)中,若该页内容缓存在内存中,直接读取返回给用户进程;若缓存不存在,则启动BIO,从硬盘读取该页面到内存,再送给用户进程;
write过程:比如往某文件5K处写入10byte,内核先查询该页是否在内存缓存(内核page
cache),不在,同read,从硬盘读取该页4~8K到内存,再往5k处写入10byte,标明该页为脏页;
写回磁盘时机,则由内存管理的BIO机制决定。
Linux读写文件两种方式:read/write,mmap
相同点:都经过page cache中介操作磁盘文件;
区别:
read/write:有一个用户空间和内核空间的拷贝过程;
mmap:指针直接操作文件映射的虚拟地址,省略了用户空间和内核空间的拷贝过程。
缺点是,很多设备不支持mmap,比如串口,键盘等都不支持。
2.free命令的详细解释
total: 系统总的内存
第一行used: 所有用掉的内存,包括app,kernel,page cached(可回收);
第一行free: =total-used
第一行buffers/cached:page cached内存
第二行free = 第一行free+buffers+cached
114380=31040+8988+74352
第二行used = 第一行used-buffers-cached
40072=123412-8988-74352
第一行used是从buddy的角度,统计所有用掉的内存(包括page cached);
第二行uesed,是从进程角度,包括app/kernel/ , 不含page cached(可回收)。
cached/buffer区别:
cached:通过文件系统访问;
buffer:裸地址直接访问,存放文件系统的元数据(组织数据的数据);
新版free,去掉了buffer/cached的区别,加入一个available,预估可用内存
在cat /proc/meminfo也可以看到预估项MemAvailable
查看实现方法git grep MemAvailable
vim fs/proc/meminfo.c
搜MemAvailable,实现函数si_mem_available
git grep
vim mmpage_alloc.c-- >long si_mem_available(void)
3.read、write和mmap
mmap映射文件过程,实际上在进程创建一个vma,映射到文件,当真正读/写文件时,分配内存,同步磁盘文件内存。
其本质是虚拟地址映射到page cached, page cached再跟文件系统对应。
这里的page cached是可以回收的。
4.file-backed的页面和匿名页
在一个elf文件中,代码段的本质,就是对应page cached;
真正执行到的代码,才会从磁盘读入内存,并且还可能被踢走,下次再执行,可能需要重新从磁盘读取。
Reclaim可回收的
有文件背景的页面,叫file-back page, 可回收
**匿名页:anon, 不可回收,常驻内存;
pmap pid
Anon: stack、heap、 CoW pages
File-backed:代码段,映射文件,可回收。
5.swap以及zRAM
案例,当同时运行word和qq,word需要400M匿名页,qq需要300M匿名页,而物理内存只有512M,如何运行呢,此时伪造一个可swap的文件,供anon匿名页交换。
在内核配置CONFIG_SWAP,支持匿名页swap,不配置,普通文件swap依然支持;
SWAP分区,对应windows的虚拟内存文件pagefile.system。
6.页面回收和LRU
局部性原理:最近活跃的就是将来活跃的,最近不活跃的,以后也不活跃。
包括时间局部性,空间局部性。
LRU:Least Recently Used最近最少使用,是一种常用的页面置换算法,
真实统计过程,无关进程,只统计页面的活跃度;
案例,开启浏览器chrome;长期不使用,运行oom.c消耗掉系统所有内存,再去第一次打开网页时,速度会很慢,因为需要重新加载被踢出去的不活跃页面。
**sudo swapoff –a**
**echo 1 > /proc/sys/vm/overcommit_memory**
**cat /proc/pid/smps >1**
**./oom.out**
**cat /proc/pid/smaps >2**
**meld 1 2**
可见命中的部分page cached,被LRU踢走。
CPU>>mm>>io
嵌入式设备,一般不用swap,不使能swap,因为:
1.嵌入式磁盘速度很慢;
2.FLASH读写寿命有限;
zRAM
在物理内存划分一部分,作为“swap”分区,用来做页面回收置换,利用强大CPU算力换取更大内存空间;
内核使能swap
echo $((48*1024*1024)) >
打开swap分区:
swapon –p 10 /dev/zram0
cat
不带pagecached的IO, direct IO。 在用户态根据业务特点做cached.
类似于CPU跳过cache,直接访问mem;