/dev/shm 中的操作导致溢出

/dev/shm 中的操作导致溢出

我在 /dev/shm 中重复数以万计的类似操作,每个操作都会创建一个目录,写入文件,然后删除。我曾经的假设是,我实际上是在创建目录并将它们就地删除,因此内存消耗必须非常低。但结果发现使用率相当高,最终导致内存溢出。所以我的问题是:像这样的操作

mkdir /dev/shm/foo
touch /dev/shm/foo/bar
[edit] /dev/shm/foo/bar
....
rm -rf /dev/shm/foo

最终会导致内存溢出吗?如果确实如此,为什么会这样,因为它似乎正在将它们就地移除。

笔记:这是数以万计的类似操作。

答案1

很好奇,当您运行此应用程序时,什么df -h /dev/shm显示了您的 RAM 使用情况?

临时文件系统

默认情况下,它通常设置为系统物理内存量的 50%。这是记录在这里在 kernel.org 上的 tmpfs 文件系统文档下。手册页中也提到了它mount

摘自安装手册页

此实例的最大索引节点数。默认值是物理 RAM 页面数量的一半,或(在具有 highmem 的机器上)lowmem RAM 页面数量的一半,以较小者为准。

确认

在我的 8GB RAM 笔记本电脑上,我进行了以下设置/dev/shm

$ df -h /dev/shm
Filesystem            Size  Used Avail Use% Mounted on
tmpfs                 3.9G  4.4M  3.9G   1% /dev/shm

这是怎么回事?

我认为正在发生的事情是,除了开始时分配 50% 的 RAM 之外,随着时间的推移,您实际上会消耗掉全部 50% 的内存,并将您的/dev/shm空间与其他 50% 的 RAM 一起推入交换区。

tmpfs请注意, vs的另一个特征ramfs是,tmpfs如果需要,可以将其放入交换中:

摘自极客网

                    Table: Comparison of ramfs and tmpfs

Experimentation                          Tmpfs                Ramfs
---------------                          -----                -----
Fill maximum space and continue writing  Will display error   Will continue writing
Fixed Size                               Yes                  No
Uses Swap                                Yes                  No
Volatile Storage                         Yes                  Yes

归根结底,它是一个在 RAM 中实现的文件系统,所以我希望它的行为有点像两者。我的意思是,当文件/目录被删除时,您将使用一些物理内存页作为 inode 表,以及一些用于这些文件/目录消耗的实际空间。

通常,当您使用 HDD 上的空间时,您实际上并没有释放物理空间,只是释放了 inode 表中的条目,表示特定文件消耗的空间现在可用。

因此,从 RAM 的角度来看,文件消耗的空间只是内存中的脏页。因此,随着时间的推移,它会尽职尽责地更换它们。

目前还不清楚是否tmpfs做了任何特殊的事情来清理它提供的文件系统使用的实际 RAM。我在几个论坛中看到有人提到,人们发现他们的系统需要 15 分钟以上才能“回收”他们在/dev/shm.

也许我发现的这篇论文tmpfs标题为:tmpfs:虚拟内存文件系统将更多地阐明它如何在较低级别实现以及它如何相对于 VMM 发挥作用。该论文是专门为 SunOS 撰写的,但可能包含一些线索。

实验

以下人为的测试似乎表明/dev/shm它能够自我清理。

实验#1

创建一个目录,其中包含单个文件,然后删除该目录 1000 次。

的初始状态/dev/shm
$ df -k /dev/shm
Filesystem           1K-blocks      Used Available Use% Mounted on
tmpfs                  3993744      5500   3988244   1% /dev/shm
用文件填充它
$ for i in `seq 1 1000`;do mkdir /dev/shm/sam; echo "$i" \
      > /dev/shm/sam/file$i; rm -fr /dev/shm/sam;done
最终状态为/dev/shm
$ df -k /dev/shm
Filesystem           1K-blocks      Used Available Use% Mounted on
tmpfs                  3993744      5528   3988216   1% /dev/shm

实验#2

创建一个目录,其中包含一个 50MB 的文件,然后删除该目录 300 次。

用 50MB 的随机垃圾文件填充它
$ start_time=`date +%s`
$ for i in `seq 1 300`;do mkdir /dev/shm/sam;                     \
   dd if=/dev/random of=/dev/shm/sam/file$i bs=52428800 count=1 > \
   /dev/shm/sam/file$i.log; rm -fr /dev/shm/sam;done              \
   && echo run time is $(expr `date +%s` - $start_time) s

...
8 bytes (8 B) copied, 0.247272 s, 0.0 kB/s
0+1 records in
0+1 records out
9 bytes (9 B) copied, 1.49836 s, 0.0 kB/s
run time is 213 s
最终状态为/dev/shm

再次,所消耗的空间没有明显增加/dev/shm

$ df -k /dev/shm
Filesystem           1K-blocks      Used Available Use% Mounted on
tmpfs                  3993744      5500   3988244   1% /dev/shm

结论

我没有注意到使用我的/dev/shm.多次运行以上似乎也没有任何影响。因此,我认为/dev/shm按照您所描述的方式使用没有任何问题。

相关内容