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)
它最终会导致内存溢出吗?如果是这样,为什么会这样,因为它似乎正在就地删除它们。
注意:这是一个数以万计的类似操作。
很好奇,当你运行这个应用程序时,df -h /dev/shm
你的 RAM 使用情况是什么?
默认情况下,它通常设置为系统实际拥有的 RAM 量的 50%。这是记录在这里对kernel.org,为的tmpfs文件系统文件下。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 一起推入交换区。
请注意,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
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
能够自我清理。
创建一个包含单个文件的目录,然后删除该目录 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)
创建一个包含单个 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
以您描述的方式使用没有任何问题。