フォークされたプロセスのセットのメモリフットプリントをどのように測定しますか?

フォークされたプロセスのセットのメモリフットプリントをどのように測定しますか?

たとえば、200MB のメモリを使用するプロセスがあり、それが fork() するとします。

python -c "import os; data='x'*200000000; os.fork(); raw_input()"

「top」のようなプログラムは、各プロセスが 200MB を使用していることを表示しますが、SHRd メモリは非常に少ないため、プロセスが合計で 400MB を使用しているように見えます。ただし、fork() はプロセスのメモリ ページにコピー オン ライト (COW) を実装するため、実際にはプロセスが合計で 200MB しか使用していません。

top はなぜメモリのどの部分が COW であるかを表示しないのでしょうか? それを表示する方法はありますか? または、代わりに使用できる別のコマンドがありますか?

注: OSX の「top」には、期待どおりの機能を果たす RSHRD 列があるようです。私の質問は Linux に関するものです。

答え1

そのような情報は、エントリ (「比例共有サイズ」の略)/proc/<pid>/smapsの形式で各プロセスのファイルから取得できます。Pss

上記の例では、2 つのプロセス間で 200 MB が「共有」されており、各プロセスはそのマッピングの PSS エントリに 100 MB を表示します。つまり、メモリはそれを共有するプロセス間で均等に分散されます (いずれかのプロセスによってコピーされ、共有解除されるまで)。

以下は、あなたが投稿したものと似たものを実行した結果の抜粋です。

$ top
...
30986 me        20   0  790m 769m 2200 S    0  4.8   0:00.48 python3.2
30987 me        20   0  790m 767m  224 S    0  4.8   0:00.00 python3.2
$ cat /proc/30986/smaps
...
0119a000-015b7000 rw-p 00000000 00:00 0                                  [heap]
Size:               4212 kB
Rss:                3924 kB
Pss:                1992 kB
...
7fa06b020000-7fa09ab11000 rw-p 00000000 00:00 0 
Size:             781252 kB
Rss:              781252 kB
Pss:              390626 kB
...
7fff8e45a000-7fff8e489000 rw-p 00000000 00:00 0                          [stack]
Size:                192 kB
Rss:                 160 kB
Pss:                  82 kB
...

(あります多くこれらのファイルには、多くのプロセス間で共有される可能性のある共有ライブラリのマッピングなど、さまざまな内容が含まれており、各プロセスはそれらの PSS エントリでそのごく一部しか取得しません。

これに関する素晴らしい記事があります: ELC:アプリケーションは実際にどれくらいのメモリを使用しているのでしょうか?

この情報を表示するための一般的なtopのようなツールは知りませんし、ps残念ながらそれを表示するオプションもないと思います。この記事では、Pythonスクリプトのリポジトリが紹介されています。pagemapただし、Matt Mackall によるもので、これを使用したり、適応したりすることはできます。

恥ずかしくない宣伝:いくつかの投稿が見つかりますUnix と LinuxPSS とsmapsファイルについて興味があれば、ご覧ください。

関連情報