如何检查分配给进程中打开文件的内存

时间:2015-06-24 21:59:42

标签: c linux memory-management memory-leaks

场景是我运行的测试程序大小增加到8GB,然后通过Check完成一系列断言。

我可以看到我的流程在' top '' top '我看到我的系统内存相应增长。但是,当之后完成大量断言时,我看到 VIRT停止增长,并且我看到我的总使用内存继续增加,因为Check正在通过断言。因此,根据顶部,没有更多的内存被提供给任何进程,但我仍然在咀嚼内存。

我按内存使用率排序,看不到其他任何东西都在保留内存。最终我达到100%交换和物理内存使用,并且该过程被杀死。

请注意,Check会分叉每个'测试'进入自己的过程。当我打破测试程序(w / ctrl + c)时,我仍然看到顶部的进程,它的VIRT仍然是8GB。

我相信Check会占用内存,因为当我取出所有断言时,这种行为不会发生。我在Check中看到创建了一个tmpfile()并用于跟踪发生的最后一个断言,并且当断言阶段开始时我看到/ tmp正在增长。如果我修改Check代码以写入/ tmp中的文件(而不是使用tmpfile()),我看到该文件增长为GBs大。

1)为什么打开文件占用的虚拟地址空间不会显示为进程的一部分'用过内存?请注意,检查分叉每个测试'。此外,即使交换已满,该文件的未使用部分是否应该被分页回内存? (写入是通过fwrite完成的,而不是mmap)

2)第二个问题,我之前没有使用过tmpfile(),但为什么在调用tmpfile()时,/ tmp中没有显示任何文件?如果是因为文件立即取消链接,这是否意味着任何未链接的文件不会出现在文件系统中? (我对unlink的作用的理解也很简陋)。

编辑:我使用Arch Linux w /内核4.0.5-1和procps-ng版本3.3.10

1 个答案:

答案 0 :(得分:0)

一个小实验表明是的,因为tmpfile是在/ tmp中创建的,它纯粹保存在内存中,因为我的内存不足,我的程序被杀了。因为程序具有最后一个打开的文件描述符,所以在程序被杀死后该文件被删除(从我的tmpfs中释放出来)。因为/ tmp 仅作为tmpfs存在于内存中,所以它不能“分页”到磁盘,因为文件系统本身仅存在于内存中,并且交换也已满,因此OOM错误。

通过对 / var / tmp 中的文件执行相同的实验,而不是在磁盘上,没有额外的内存被占用,所以我没有收到此错误。

虽然我无法通过顶部查看此行为,但 free -h 显示正在共享下占用的内存浅黄色/高速缓存。 为了缩小确切的罪魁祸首,我使用了:

lsof | awk '$5 == "REG"' | sort -n -r -k 7,7 | head -n 5

来自https://serverfault.com/questions/207100/how-can-i-find-phantom-storage-usage

请注意,如果/ tmp已满,则上述操作无效。 所以打开文件不是问题,即缓冲不是问题。问题是该文件存在于tmpfs中。

要回答我的#2 ,该文件不会显示,因为当它与tmpfile()取消链接时它已被“删除”:

$ lsof | awk '$5 == "REG"' | sort -n -r -k 7,7 | head -n 5
toy       13624       me    3u      REG               0,33 4294963200   12505948 /tmp/tmpf0W4HOM (deleted)