2022 年 08 月 01 日 Linux 技術ネタ
組込み Linux において、ユーザ空間で動作させているプロセスがどのぐらいメモリを使用しているか知りたくなることがあると思います(例えば Web ブラウザや、動画再生アプリなど)。
このブログエントリでは組込み Linux の環境で確認できうる、プロセスのメモリ使用量に関する指標(VSS, RSS, PSS, USS)を説明します。また、それらの指標をどのように活用できるか紹介します。
プロセスのメモリ使用量に関する主要な指標としては、以下の 4 つがあります。
Linux カーネルには、これらを取得するための機構が備わっています。また、プロセス単位で集計して見やすく表示するアプリケーションも公開されています。まずはそれぞれの指標について説明します。
VSS (Virtual Set Size) は、プロセスがアクセスできるメモリ領域サイズの総和です。VSS には仮想メモリ上にのみ確保されている領域も計上されるため、プロセスがまだ使用していないメモリ領域も含まれます。例えば C 言語のプログラムの場合、malloc で確保はしたもののまだ書き込みを行っていないメモリ領域は物理メモリ上に確保されていません。このような領域も、VSS には計上されます。そのため、プロセスが実際にどれだけ物理メモリを使用しているかについては、VSS を確認するだけでは判別できません。
なお、Virtual Set Size という名称の代わりに Virtual Memory Size という名称が使われたり、VSZ という略記が使われたりすることもあります。
RSS (Resident Set Size) は、プロセスが確保している物理メモリの使用量です。物理メモリの使用量の指標として、RSS は VSS よりも役に立ちます。
しかし、RSS には注意点が一つあります。RSS は複数のプロセス間で共有されているメモリ領域も合計して算出するという点です。例えば以下の図1で示すように、プロセス A と B について考えます。それぞれ計測時点において、メモリ使用量が以下の状況になっていると仮定します。
図 1 :ユーザ空間のプロセスによる物理メモリの使用量の例
(「共有ライブラリ」のメモリ使用量 4MB は、全てプロセス A と B のみで共有されているとします。)
このときプロセス A, B に関して、VSS および RSS は以下となります。
各プロセスの VSS と RSS は上記のように求めることができましたが、単に RSS を足し合わせるだけでは、プロセス A, B が使用している物理メモリの合計を正しく求めることはできません。なぜなら共有ライブラリの 4MB 分が A と B 両方の RSS に計上されており、そのまま足し合わせると共有ライブラリの分を重複して数えることになるためです。
上記の例のように RSS では共有メモリの領域については考慮されておらず、そのまま RSS の数値に計上されています。そのため RSS に着目しても、ユーザ空間のプロセスによって物理メモリがどのように使用されているかはよく分からない恐れがあります(複数のプロセスで共有されているのか、あるいは単一のプロセスで占有されているのかなど)。
また、物理メモリの使用量が大きなプロセスを特定したい場合、 RSS の値を基準に探したところで見つけにくいという懸念点もあります。なぜなら比較的大きな共有ライブラリを使用しているだけで RSS は大きくなりがちだからです。
先ほど述べた RSS の注意点を回避するため、PSS (Proportional Set Size) というメモリ使用量の指標が 2007 年に Selenic Consulting 社の Matt Mackall さんによって提案されました。PSS は、 RSS のうち共有メモリの使用量をプロセス間で等分することで得られる物理メモリの使用量です。先ほどの例の場合は、 4MB の共有ライブラリがプロセス A 、B によって共有されていました。そのため以下の図 2 のように A, B それぞれの PSS の計算において、共有ライブラリ 4MB を 2 等分して算出します。
図 2:PSSの計算方法の図示
プロセス A, B の PSS を足し合わせると 5 + 6 = 11MB となり、先ほど述べた実際の物理メモリの使用量の合計と一致します。
PSS を利用することにより、物理メモリの使用量が大きなプロセスを特定しやすくなります。以下のいずれかの特徴を持つプロセスは、 PSS の値が比較的大きくなる傾向にあります。
そのため物理メモリの使用量が大きなプロセスを特定したい場合、まずは PSS が大きな値を示しているプロセスに着目してみるのが良いと思います。 また、全ユーザプロセスが使用している物理メモリの総和を知りたい場合、PSS を全て足し合わせることで算出することも可能です。
物理メモリの使用量が大きなプロセスを特定したい場合に、PSS が役に立つことを説明しました。ただしプロセスを終了させたときに物理メモリがどれだけ解放されるかについては、PSS で正確に見積もることはできません。おさらいとして、ここまでの例で用いたプロセス A, B に関する VSS, RSS, PSS の数値を以下の図 3 に示します。
図 3 :VSS, RSS, PSS の計算例
ここまでの例で示した状況でプロセス A が終了させられても、A の PSS である 5MB がそのまま解放されるわけではありません。なぜならプロセス B と共有されていた分の物理メモリは、プロセス B も終了させられなければ解放されないためです。実際にはプロセス A が使用していた以下メモリ領域のうち、共有されていなかった物理メモリ 2 + 1 = 3MB のみがプロセス終了時に解放されます。
この数値 (3MB) が、プロセス A の USS (Unique Set Size) と呼ばれる指標に相当しています。USS は、プロセスが確保している物理メモリ (RSS) のうち、他のどのプロセスとも共有していない領域の合計サイズです。
プロセスA、B が両方とも存在しているとき、それぞれの USS は以下の数値となります。
あるプロセスが終了した際に解放されるメモリ使用量は、USS で知ることができます。
ここまで紹介したプロセスのメモリ使用量の各指標 (VSS, RSS, PSS, USS) について、確認方法や使い道について紹介します。なおこのブログエントリでは、以下の各種コマンドを Ubuntu 18.04 で試しました。
VSS や RSS については、 Linux でよく使われている top コマンドや ps コマンドで確認できます。 top コマンドの場合、オプションを付けずにそのまま実行するだけで VSS, RSS を確認できます。top コマンドを実行している間は、各プロセスに関して常に最新の状態に更新されます。
$ top top - 16:26:12 up 6:55, 1 user, load average: 0.42, 0.17, 0.08 Tasks: 329 total, 1 running, 248 sleeping, 0 stopped, 0 zombie %Cpu(s): 0.5 us, 0.3 sy, 0.0 ni, 98.4 id, 0.8 wa, 0.0 hi, 0.0 si, 0.0 st KiB Mem : 16077404 total, 4930584 free, 1246056 used, 9900764 buff/cache KiB Swap: 999420 total, 998896 free, 524 used. 14170400 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 775 ubuntu 20 0 45400 4104 3336 R 6.2 0.0 0:00.01 top 1 root 20 0 225796 9216 6416 S 0.0 0.1 0:07.31 systemd 2 root 20 0 0 0 0 S 0.0 0.0 0:00.02 kthreadd 4 root 0 -20 0 0 0 I 0.0 0.0 0:00.00 kworker/0:0H ...
"VIRT" の列が VSS、"RES" の列が RSS を表しています。
ps コマンドの場合、`ps aux` と引数を付けて実行することで VSS, RSS を確認できます。
$ ps aux USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.0 225796 9216 ? Ss 09:30 0:07 /sbin/init splash root 2 0.0 0.0 0 0 ? S 09:30 0:00 [kthreadd] root 4 0.0 0.0 0 0 ? I< 09:30 0:00 [kworker/0:0H] root 6 0.0 0.0 0 0 ? I< 09:30 0:00 [mm_percpu_wq] root 7 0.0 0.0 0 0 ? S 09:30 0:00 [ksoftirqd/0] root 8 0.0 0.0 0 0 ? I 09:30 0:05 [rcu_sched] root 9 0.0 0.0 0 0 ? I 09:30 0:00 [rcu_bh] root 10 0.0 0.0 0 0 ? S 09:30 0:00 [migration/0] ...
"VSZ" の列が VSS、"RSS" の列が RSS を表しています。
PSS や USS を確認したい場合は、smem という python スクリプトがおすすめです。smem を実行することにより、プロセス毎の PSS や USSをまとめて確認できます。Ubuntu 18.04 で試される場合は、以下のコマンドでインストールしてください (Ubuntu 20.04/22.04 でも同様のコマンドでインストールできるようです)。
$ sudo apt install smem
smem を実行する際は `-n` オプションを付けると、プロセスの実行ユーザが番号表記になるため表示結果が崩れにくくなります。ただし smem の注意点として、 top や ps とは異なり、全ユーザのプロセスを確認したい場合はスーパーユーザで実行する必要があります。smem はデフォルトで各プロセスのメモリ使用量に関して、PSS の値で昇順にソートした結果を出力します。そのため、後の行に表示されたプロセスほど PSS の値が大きいことを意味します。
$ sudo smem -n PID User Command Swap USS PSS RSS 1382 0 /usr/sbin/acpid 0 208 221 1912 520 0 /usr/sbin/blkmapd 0 236 277 1940 3024 0 /usr/sbin/dnsmasq --conf-fi 0 72 287 752 1393 0 /usr/sbin/cron -f 0 328 357 3248 1671 116 avahi-daemon: chroot helpe 0 132 375 1412 3171 109 /usr/lib/rtkit/rtkit-daemon 0 384 404 3208 2641 0 /usr/sbin/xinetd -pidfile / 0 412 424 2568 ...
応用として、以下のコマンドを実行すれば各プロセスの PSS の総和を求めることが可能です。
$ sudo smem -n | tail -n +2 | awk '{sum+=$6} END {print sum}' 1570458
これにより、ユーザ空間のプロセス全てで確保されている物理メモリの使用量を計算することが可能です。
Linux カーネルで利用できるメモリ使用量の指標として VSS, RSS, PSS, USS があることを説明しました。
また smem を使うことにより、特に役立つ指標である PSS と USS を確認できることを説明しました。
物理メモリの使用量が大きなプロセスを特定したい場合、まずは PSS が大きな値を示しているプロセスに着目してみるのが良いと思います。また PSS を見れば、ユーザ空間全体のプロセスで確保されている物理メモリの使用量を正確に計算することが可能です。さらに USS を見ることにより、プロセス終了時に解放される物理メモリの使用量が分かります。 ユーザ空間の各プロセスがどのぐらいメモリを使用しているかに関して、実際にプロセスを実行しながら PSS や USS の値を計測することをおすすめします。
2024 年 09 月 02 日 Vigiles サポート
2024 年 03 月 01 日 Vigiles サポート
2023 年 08 月 28 日 Vigiles サポート
2024 年 03 月 26 日 Yocto Project よもやま話
2023 年 07 月 25 日 Yocto Project よもやま話
2023 年 06 月 20 日 Yocto Project よもやま話
2024 年 01 月 10 日 Linux 技術ネタ
2023 年 12 月 12 日 Linux 技術ネタ
2023 年 03 月 31 日 Linux 技術ネタ
2024 年 12 月 06 日 イベントレポート
2024 年 07 月 26 日 イベントレポート
2024 年 07 月 09 日 イベントレポート
2023 年 05 月 30 日 リクルート
2022 年 12 月 27 日 リクルート
2022 年 09 月 27 日 リクルート
2024 年 11 月 29 日 信州リネオ便り
2024 年 09 月 25 日 信州リネオ便り
2024 年 08 月 20 日 信州リネオ便り
2019 年 12 月 10 日 ソリューション統括部
2019 年 12 月 10 日 ソリューション統括部
2019 年 12 月 10 日 ソリューション統括部
2019 年 12 月 13 日 マーケティング統括部
2019 年 04 月 25 日 マーケティング統括部
2018 年 12 月 18 日 マーケティング統括部