ramfs算是一个比较难搜到教程的话题,google和chatgpt都找不到太多有关ramfs的资料。
比如df这个命令就不显示ramfs,只显示tmpfs,有些网上的回答说redhat有个显示ramfs的补丁,但似乎有点麻烦...算了不找了。
所以为了验证某些有关ramfs的想法,只能跑一些极端的命令,配上系统资源监测来看看ramfs的实际作用到底是什么。
注:原本打算在docker上面测试的,但不知道为什么网上找的参数 --cap-add SYS_ADMIN 加上去以后仍然没有用,所以只能拿真机测试了...
目的是解决这几个疑问:
- mount ramfs的时候,是不是真的分配了RAM(而不是磁盘空间/混合了swap内存)
- mount ramfs时分配的size,理论上是无法对ramfs起约束的(理论上它会越来越大,直到物理内存被吃完),是否真的如此?
- ramfs的真实占用空间,是由mount命令的参数size决定,还是由ramfs存放文件的体积决定,还是两者都有?
验证方法:
用一台大内存机器(128GB RAM,ubuntu 22.04,Linux 6.5.0)跑的,配上dd命令和netdata的资源监控
结论:
- mount ramfs的时候,不会分配任何RAM空间。
- mount ramfs时的size参数似乎并没有什么作用:无论size等于多少,或者不声明size,都不会分配任何RAM空间。size这个参数也可以去掉。
- 往ramfs里面写文件的时候,分配到了真正的RAM空间(而不是磁盘空间/swap内存):写1GB文件就分配1GB空间,写2GB文件就分配2GB空间(假设RAM足够)。
- 从ramfs里面删文件的时候,会立即回收这个文件占用的RAM空间:删1GB文件就归还1GB内存,删2GB文件就归还2GB内存。
- 综合上面2条,ramfs占用的空间就是ramfs存储文件的真实占用空间。
步骤:
先挂载一个45M大小的ramfs(这个size=45M后面会解释它实际上没有任何作用):
mount -t ramfs -o size=45M ramfs /var/test_ramfs
然后往里面先塞1个1gb大小的文件,然后删了,然后再建一个1gb大小的文件,再塞1个2gb大小的文件
dd if=/dev/zero of=/var/test_ramfs/1gb bs=1M count=1024
rm /var/test_ramfs/1gb
dd if=/dev/zero of=/var/test_ramfs/1gb bs=1M count=1024
dd if=/dev/zero of=/var/test_ramfs/2gb bs=1M count=2048
然后直接卸载这个ramfs:(不删文件)
umount /var/test_ramfs/
netdata显示的ram使用率:
可以看出来,所谓size=45MB这个声明确实没有什么限制作用,该吃的内存照样会吃。当然,删除文件以后,占用的RAM空间也会马上归还。
再看看对应的磁盘IO(注意单位是kb/s):
可以认为上面那几个GB级别的dd命令是完全不作用于硬盘的。所以ramfs确实是作用在了真实的RAM上面。
那么,如果挂载一个(size声明为)1GB的ramfs:
mount -t ramfs -o size=1GB ramfs /var/test_ramfs
会立即占用1GB的内存吗?
答案是不会。(ram毫无波动)
只有往ramfs里面写了文件,它才会被占用。
后续我甚至试了挂载(size声明为)50GB,250GB的ramfs,结论是:
无论挂载多大的ramfs,似乎都没有任何区别,mount命令永远是秒执行,ram也不会有任何波动。你甚至可以挂载超过系统物理内存的ramfs,不会报错,也不会对ram起任何影响。(只要不往里面写文件)
那么,mount命令里的size=1GB可以省略吗?
可以。
$ mount -t ramfs ramfs /var/test_ramfs/
再试试挂载(size声明为)1MB的ramfs(以及不声明size),然后写入20GB的文件:
没有任何问题!
网上有些说法是ramfs不能占用超过系统物理内存的一半,这台机器是128GB RAM,试试往ramfs里面写入80GB文件:
没有任何问题!
由于担心出问题,写入更多(超过128GB)的测试就不做了。