我正在使用 Linuxps
命令监控 Docker 容器内部进程的 RSS 大小。如果总 RSS 超过阈值,则测试失败并开始寻找内存回归。
ps
以下是Docker 容器内部的完整输出。
PID %CPU RSS Threads COMMAND
1 0.0 2616 1 sh /test/Build/unittest.sh
7 3.3 44240 1 /usr/bin/Xvfb :1 -screen 0 ...
17 1.5 10824 1 /usr/bin/fluxbox
357 690 6292244 324 java -server -Xmx2g ...
490 0.4 7852 1 /usr/bin/python /usr/bin/dstat ...
491 0.7 7812 1 /usr/bin/python /usr/bin/dstat ...
1331 0.0 3040 1 /usr/bin/ps -AHww --format ...
1332 0.0 380 1 /usr/bin/ls --all ...
1333 0.0 6292248 1 [NDR-347]
Java 进程 (pid: 357) 创建了短暂的子进程。在上面的输出中,您可以看到 2 个 dstat Python 进程,ps、ls 和 [NDR-347]”。这些都是由 Java 进程创建的。
有时,我会看到重复的子进程(即相同的命令)但进程 ID 不同(未显示)。为什么我会看到重复的子进程?我认为这是某种 Linux 或 Docker 工件。那是什么工件?
我已经监控ps
输出一年多了。这是我第一次看到一个额外的进程“[NDR-347]”(pid:1333),其 RSS 几乎相同。Java 进程(pid:357)将线程命名为“NDR-#”,因此我觉得子进程的命令会是来自 Java 进程的线程的名称,这很奇怪。额外的进程使 RSS 翻倍并引发问题。该问题无法重现。这说明 pid 1333 的寿命非常短,并且没有被捕获ps
。总 RSS 为 12.07 GB,如果没有额外的进程,则为 6.07 GB。这个额外的进程是什么?为什么它的 RSS 如此之大?
编辑:确切的ps
命令是......
ps -Ahww --format pid,%cpu,rss:8,nlwp=Threads,command
答案1
您有一个运行其他程序的 Java 进程。
与任何其他想要运行另一个程序的进程一样,第一步是fork
。这个分叉进程继承了父进程的内存映射。此内存是共享的,因此它实际上并不使用额外的 RAM。
下一步fork
是execve
新进程。execve
释放所有内存并从新程序映射内存。
通常,execve
在之后会很快出现fork
,因此您不太可能捕获处于这种状态的进程,但偶尔会发生。
在您的特定情况下,如果您知道分叉的 Java 进程包含名称NDR-
,那么您应该忽略这些进程。