我们在托管 SAP 应用程序的服务器上有 1TB 内存。
当应用程序运行时,显示的内存使用top
量约为 700GB。当应用程序停止时,显示的内存使用量top
将降至 10GB。重新启动服务器会使内存使用量达到 1GB。
- 即使没有运行任何应用程序,为什么
top
显示已使用 10GB,重启后却增加了 9GB? - 是否有可能在不重新启动的情况下获得 9GB?
输出free -g
:
free -g
total used free shared buffers cached
Mem: 1009 567 442 0 0 152
-/+ buffers/cache: 415 594
Swap: 1 0 1
答案1
Linux 使用 RAM 的方式与其他操作系统不同。
Linux 不是将未使用的 RAM 坐在那里,而是存储它所需要的数据。想可能在 RAM 中使用——任何应用程序、文件等都可以缓存在这里。
因此,Linux RAM 使用量高于运行应用程序所使用的量。这种额外的使用会被缓冲以被其他事物起诉。运行free -h
第二行用过的会告诉你很多“已用”内存实际上只是被缓存了。
在所有内存都被缓存并且程序需要内存的情况下,它将从缓存中删除足够的内存以适应该程序。
答案2
这是因为尽管应用程序已停止,但某些文件描述符仍然打开。您可以使用提到的技术列出打开的文件描述符这里。
如果您需要在不重新启动的情况下关闭文件描述符,您可以按照 Graeme 提到的方法这里但是,您需要了解要关闭的文件描述符,正如 Graeme 在他的回答中强调的那样。他的回答是,
从字面上回答,关闭全部打开文件描述符
bash
:for fd in $(ls /proc/$$/fd); do eval "exec $fd>&-" done
然而,这确实不是一个好主意,因为它将关闭 shell 输入和输出所需的基本文件描述符。如果这样做,您运行的任何程序都不会在终端上显示其输出(除非它们
tty
直接写入设备)。事实上,在我的测试中,关闭stdin
(exec 0>&-
) 只会导致交互式 shell 退出。您实际上可能想做的是关闭所有不属于 shell 基本操作的文件描述符。这些是 0
stdin
、 1stdout
和 2stderr
。除此之外,一些 shell 似乎还默认打开其他文件描述符。你bash
有 255 个(也用于终端 I/O),dash
我有 10 个,它指向/dev/tty
而不是终端正在使用的特定tty
/设备。pts
要关闭 中除 0、1、2 和 255 之外的所有内容bash
:for fd in $(ls /proc/$$/fd); do case "$fd" in 0|1|2|255) ;; *) eval "exec $fd>&-" ;; esac done
另请注意,
eval
重定向变量中包含的文件描述符时是必需的,如果不是,bash 将扩展变量,但将其视为命令的一部分(在这种情况下,它将尝试exec
命令0
或1
或您尝试关闭的任何文件描述符) 。另外使用 glob 而不是ls
(eg/proc/$$/fd/*
) 似乎会为 glob 打开一个额外的文件描述符,因此ls
似乎是这里的最佳解决方案。更新
有关可移植性的更多信息
/proc/$$/fd
,请参阅 文件描述符链接的可移植性。如果不可用,则, using (如果可用)/proc/$$/fd
的替代品 将是。$(ls /proc/$$/fd)
lsof
$(lsof -p $$ -Ff | grep f[0-9] | cut -c 2-)