场景是我运行的测试程序大小增加到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
答案 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)