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

Dan*_*iel 7 linux memory shared-memory

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

mkdir /dev/shm/foo
touch /dev/shm/foo/bar
[edit] /dev/shm/foo/bar
....
rm -rf /dev/shm/foo
Run Code Online (Sandbox Code Playgroud)

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

注意:这是一个数以万计的类似操作。

slm*_*slm 6

很好奇,当你运行这个应用程序时,df -h /dev/shm你的 RAM 使用情况是什么?

tmpfs

默认情况下,它通常设置为系统实际拥有的 RAM 量的 50%。这是记录在这里对kernel.org,为的tmpfs文件系统文件下。mount手册页中也提到了它。

摘自mount 手册页

此实例的最大 inode 数。默认值是物理 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
Run Code Online (Sandbox Code Playgroud)

这是怎么回事?

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

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

摘自geekstuff.com

                    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
Run Code Online (Sandbox Code Playgroud)

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

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

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

目前尚不清楚是否tmpfs有任何特殊措施来清理它提供的文件系统使用的实际 RAM。我在几个论坛上看到有人提到他们的系统需要 15 分钟以上的时间来“回收”他们在/dev/shm.

也许我在tmpfs题为:tmpfs: A Virtual Memory File System上找到的这篇论文将更多地阐明它是如何在较低级别实现的,以及它如何相对于 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
Run Code Online (Sandbox Code Playgroud) 用文件填充它
$ for i in `seq 1 1000`;do mkdir /dev/shm/sam; echo "$i" \
      > /dev/shm/sam/file$i; rm -fr /dev/shm/sam;done
Run Code Online (Sandbox Code Playgroud) 最终状态 /dev/shm
$ df -k /dev/shm
Filesystem           1K-blocks      Used Available Use% Mounted on
tmpfs                  3993744      5528   3988216   1% /dev/shm
Run Code Online (Sandbox Code Playgroud)

实验#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
Run Code Online (Sandbox Code Playgroud) 最终状态 /dev/shm

再次没有显着增加/dev/shm.

$ df -k /dev/shm
Filesystem           1K-blocks      Used Available Use% Mounted on
tmpfs                  3993744      5500   3988244   1% /dev/shm
Run Code Online (Sandbox Code Playgroud)

结论

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