当前位置: 首页 > 科技观察

救命,Linux正在吞噬我的记忆!

时间:2023-03-19 13:54:28 科技观察

内存发现它的空闲空间越来越少了。经过一番调查,发现罪魁祸首是Linux老大!内存:linux老大,运行的程序不多,你怎么老占着我的内存啊,内存都快被你吃光了!linux:你的容量那么大,空间闲置,我把空闲空间都用来做文件缓存!内存:你看你把这个文件“Disassembled”存成4K的碎片,这里放一块,那里放一块,把我的内存空间搞得乱七八糟。Linux:这称为页面缓存。事实上,它一点也不乱。文件存放在内存的哪“片”我记得清清楚楚,我也是迫不得已,硬盘太慢了,比你的慢几万倍。CPU的一秒在这里是6分钟,在硬盘上是几个月!每次我从他那里读取一些数据,要等好几个月才能回复我,所以我只好先把读取的数据缓存给你。看到这个身影,记忆不由啧了一声:没想到外面的世界这么慢!此时,一个名为helloworld的程序想要读取该文件。helloworld:老大,我给你发了一个read系统调用,读取config.txt的前1024字节,并将结果放入我的缓冲区。Linux:好的,让我看看config.txt是否已经在页面缓存中,不幸的是,它还没有被缓存。内存哥们,我又要吃你的空闲空间了。Linux在内存中分配一个4k的页框,向硬盘发送DMA命令,读取cong.txt的4k数据。内存感觉怪怪的:helloworld只要1024字节,为什么要让硬盘发送超过4K的数据?linux:我这边的pagecache都是4K单位的,看一遍要好几个月,要不你多看点?何况helloworld很有可能会继续读取文件的后续部分,下次他就不需要访问硬盘了。“几个月”后,硬盘的数据被复制到内存的Pagecache中。记忆说:到此结束了吧?Linux:怎么可能!我必须从页面缓存中取出前1024个字节并将它们复制到缓冲区中指定的helloworld。这个buffer其实就是helloworld虚拟地址空间在堆上的地址,物理地址也在你的内存中。记忆:我的天哪!我的内存中有两份数据吗?Linux:没错!你不知道,复制数据需要CPU!这很费力。helloworld:老大,能不能让我直接访问你Page缓存里的数据?Linux:那怎么样?你在用户空间,我在内核空间。如果你能访问它,你要是惹我怎么办?必须禁止!内存:嗯,有道理,但是如果有另一个程序也读取config.txt的前1024字节,我该怎么办?Linux:这很简单。我可以查到数据已经在Pagecache里了,不用等几个月再从硬盘读取,直接copy到那个程序的buffer里就可以了。记忆:嗯?这个数据重复太多了!Linux:嗯,确实是个问题。现在这些程序频繁访问几十个文件,每个程序都拷贝一份,确实是一种巨大的浪费。内存:让我给你一个技巧。由于那些程序运行和访问的是虚拟地址,如果你将这些虚拟地址映射到Pagecache,那么每个人都可以共享它们。Linux:好主意,我提供一个系统调用mmap来完成你说的功能。helloworld运行并退出。内存:helloworld已经退出了,请问您稍后会清理相应的pagecache吗?Linux:还没有!内存:啊?难怪你正在吃掉所有的内存!Linux:唉,你的内存也闲置了,文件缓存起来了,下次再访问,性能会大大提高!别担心,我会在适当的时候清除页面缓存。内存:如果helloword修改了文件内容怎么办?会立即写入硬盘吗?Linux:没有,我只是将Pagecache标记为“dirty”,然后我定期写入硬盘。内存:你怎么能这样!这不是在欺骗那些程序吗?如果停电了怎么办?Linux:对于需要及时写入硬盘的,有两种方法,一种是调用我提供的fsync方法强制写入硬盘,另一种是在访问文件的时候,可以指定不要使用页面缓存。Memory:相当于什么都不说了,没有Pagecache有多慢。Linux:你现在知道页面缓存的重要性了。pagecache是??一种比较通用的文件缓存机制,由我来管理。对于一些应用,比如数据库,他需要更灵活更复杂的文件缓存,所以他不需要pagecache,从头开始。记忆:嗯?数据库也在用我做缓存?Linux:哈哈,对,怪硬盘,谁让这么慢!但是要是跟你一样快,你的孩子就要下岗了,你想想,在一块存取速度超快、容量超大、还不怕断电威胁的内存面前,你会变成渣男吗?记忆叹了口气:好吧,我管不了了,你想怎么样就怎么样吧。后记:本文首图及标题来自https://www.linuxatemyram.com/,文章内容参考https://manybutfinite.com/post/page-cache-the-affair-between-memory-and-files/,准确的说,这篇文章是加料的改编版。这个博客还有几篇关于虚拟内存的文章,非常不错。我强烈建议您阅读英文原版文章。