Linuxプロセスのピークメモリ使用量
1. 概要
Linuxは、その設計により、利用可能なすべての物理メモリを可能な限り効率的に使用することを目的としています。 ただし、システムリソースの制限により、サーバー側で突然の動作が発生する場合があります。 通常、これらの制限により、CPUとメモリの使用率が高くなります。 いずれにせよ、プロセスのメモリ使用率を観察することで、このような突然の動作を実際に回避することができます。
このチュートリアルでは、プロセスのピークメモリ使用量を認識するのに役立つ、いくつかのよく知られたLinuxコマンドを使用していくつかのヒントとコツを実装する方法を学びます。
2. メモリを監視するための従来のコマンド
ほとんどの場合、 top / htop /atopのようなコマンドでプロセスの概要がわかります。 特定のケースでは、特定のプロセスを監視するために使用することもできます。 ここでは、プロセスのチェックに焦点を当てて、そのピークメモリ使用率を特定します。
トップの結果を調査して、プロセスの概要を確認することから始めます。 これにより、すべてのプロセスが何を使用しているかがわかります。
特定のプロセスに焦点を合わせる必要があり、そのプロセスID(PID)がわかっているとします。
$ top -p 7
top - 10:25:53 up 19 min, 0 users, load average: 0.52, 0.58, 0.59
Tasks: 1 total, 0 running, 1 sleeping, 0 stopped, 0 zombie
%Cpu(s): 16.0 us, 6.2 sy, 0.0 ni, 77.1 id, 0.0 wa, 0.7 hi, 0.0 si, 0.0 st
MiB Mem : 3961.1 total, 665.1 free, 3072.0 used, 224.0 buff/cache
MiB Swap: 12288.0 total, 11806.3 free, 481.7 used. 758.5 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
7 user1 20 0 18076 3632 3528 S 0.0 0.1 0:00.19 bash
次に、bashの使用法を見ていきます。
$ top | grep bash
7 user1 20 0 18076 3632 3528 S 0.0 0.1 0:00.19 bash
73 root 20 0 18076 3604 3540 S 0.0 0.1 0:00.17 bash
htopはtop、に似ていますが、プロセスに関するより多くのデータを表示します。 プロセスパスを認識するのに便利なコマンド列があります。
atop も、topやhtopのようなコマンドです。 その利点は、出力をファイルに記録するという非常に便利な機能です。
特定の時間枠で何度も発生する問題について考えてみます。 記録を保持するために、出力をファイルに書き込むためのcronジョブをスケジュールできるため、後で再生できるようになります。 出力をファイルに記録する必要がある場合は、 atop-wを使用します。
$ atop -w filename
また、そのファイルからの出力を再生する必要がある場合は、 atop-rを使用します。
$ atop -r filename
PID SYSCPU USRCPU VGROW RGROW RUID EUID ST EXC THR S CPUNR CPU CMD 1/1 73 0.17s 0.03s 481.1G 3604K root root N- - 1 S 0 0% bash
7 0.10s 0.09s 591.0G 3632K user1 user1 N- - 1 S 0 0% bash
1 0.15s 0.00s 376.9G 316K root root N- - 2 S 0 0% init
71 0.04s 0.00s 716.4G 2908K root root N- - 1 S 0 0% sudo
72 0.03s 0.00s 820.0G 2092K root root N- - 1 S 0 0% su
109 0.01s 0.00s 1.0T 2136K root root N- - 1 R 0 0% atop
6 0.00s 0.01s 376.9G 224K root root N- - 1 S 0 0% init
これらの3つのコマンドは、継続的な調査に最適なツールです。 私たちの状況では、プロセスが設定された制限に達する前に、プロセスのピークメモリ使用量を特定できます。
3. grepワンライナー
/ proc仮想ファイルシステムは、Linuxカーネルの現在の状態を表すファイルの階層を含むディレクトリです。 また、現在実行中のプロセスに関する情報も含まれています。
これは、プロセスID(PID)113を持つそのようなプロセスのピークメモリ使用量を決定するワンライナーです。
$ grep ^VmPeak /proc/113/status
VmPeak: 2252 kB
また、RAM使用量を測定するために「VmHWM:ピーク常駐セットサイズ」を探すこともできます。 VmPeakは、仮想メモリを含む最大合計メモリ使用量であり、VmHWMはピークRAM使用量です。
ご存知のように、 / proc は仮想ファイルシステムであるため、そのファイルからの読み取りは、通常のファイルシステムからの読み取りと同じではありません。 プロセスに関する情報は、実際のファイルシステムの場合よりもはるかに高速に / proc から削除されます(ダーティキャッシュフラッシングがここに含まれます)。
これを念頭に置いて、まだバッファリングされていないプロセスの次の行を読み取る必要があると想像してください。 この場合、それに関する情報はすでに削除されている可能性があります。 存在しなくなったプロセスに関する情報は必要ない場合があります。 解決策は、ファイルの損失を考慮するか、ファイル全体をバッファリングしてから解析することです。
4. GNU時間
いくつかの例を見て、与えられたコンテキストでのGNU timeを理解しましょう。
‘top‘プロセスのピークメモリ使用量を知りたいとします。 この場合、次のように通知するのは「最大常駐セットサイズ」です。
$ /usr/bin/time -v top | grep "Maximum resident set size"
Maximum resident set size (kbytes): 2252
GNU timeはフォーマットオプションをサポートしています。 メモリ使用量とは別に、%Pオプションを指定したGNU time は、無関係な統計(%CPU)を提供します。これは、スケジューラーに依存するため、非常に変動します。
$ /usr/bin/time -f "%P %M" top
2% 2248
bashでは、/ usr / bin / timeなどのフルパスを指定する必要があります。これは、bashの組み込みtimeキーワードが-fオプションをサポートしていないためです:
$ /usr/bin/time -f '%M' top
2248
また、エイリアスを作成したり、GNU timeを使用して平均および最大のメモリ情報を取得するように環境を調整したりすることもできます。
alias time="$(which time) -f '\t%E real,\t%U user,\t%S sys,\t%K amem,\t%M mmem'"
export TIME="$(which time) -f '\t%E real,\t%U user,\t%S sys,\t%K amem,\t%M mmem'"
メモリセグメントに格納されているこの情報は、プロセスの平均合計(データ+スタック+テキスト)メモリ使用量(K)と最大常駐セットサイズ(M)を表します。
4.1. 議論と考察
time コマンドのファクトチェックを実行して、既知の問題のいくつかについて説明します。
最初の問題は、一部のLinuxシステムでメモリレポートの時間が壊れている可能性があることです。 / usr / bin / time -v ls を使用して「最大常駐セットサイズ」を決定すると、ほとんどの場合、0が返されることがわかります。 timeはwait3(2)システムコールからほとんどの情報を取得するため、常に0を返します。
wait3(2)コールがないシステムでは、代わりに time(2)システムコールを使用してください。 ただし、 wait3(2)よりもはるかに少ない情報を提供します。 したがって、このようなシステムは、リソースの大部分を0として報告します。
または、CPUを集中的に使用するコマンドを試してみるとうまくいく場合があります。
2番目の問題は、 time -v を呼び出すと、出力「bash:-v:コマンドが見つかりません」は、bashがtimeをインターセプトして独自のビルドを使用することを意味します-time関数で。 / bin / time-vを使用すると問題が解決します。
第三に、GNU時間にはバグがあります。 実際のメモリ使用量の4倍を報告します。 Ubuntu14.4のtime1.7-24およびバージョン1.7-3のFedoraのtimeパッケージには、メモリレポートの修正が組み込まれています。
4.2. ビルトイン時間対。 GNU時間
上記のように、bashでは、GNU time へのフルパスを指定する必要があります(例: / usr / bin / time )。 または、コマンド時間-lを使用することもできます。
コマンドはプレースホルダーではないことに注意してください。 コマンド時間は、時間とは異なります。 コマンドtime-lはシェルを呼び出して、組み込み関数の代わりにtimeと呼ばれるバイナリを呼び出します。
5. Valgrindワンライナー
Valgrind は、ユーザースペースバイナリにインストルメンテーションを提供するフレームワークです。 プログラムのパフォーマンスのプロファイリングと分析に使用できるいくつかのツールが付属しています。
Valgrind ツールの1つであるMassifは、特定のプログラムによって使用されるヒープメモリを測定します。 ‘top‘プロセスのピークメモリ使用量を表す単純なvalgrindmassifワンライナーは次のようになります。
$ valgrind --tool=massif --pages-as-heap=yes --massif-out-file=massif.out top; grep mem_heap_B massif.out | sed -e 's/mem_heap_B=\(.*\)/\1/' | sort -g | tail -n 1
==746== Massif, a heap profiler
==746== Copyright (C) 2003-2017, and GNU GPL'd, by Nicholas Nethercote
==746== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==746== Command: top
==746==
==746== error calling PR_SET_PTRACER, vgdb might block
top - 21:47:03 up 23 min, 0 users, load average: 0.52, 0.58, 0.59
Tasks: 8 total, 1 running, 6 sleeping, 1 stopped, 0 zombie
%Cpu(s): 2.8 us, 1.9 sy, 0.0 ni, 95.3 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
MiB Mem : 3961.1 total, 408.3 free, 3328.8 used, 224.0 buff/cache
MiB Swap: 12288.0 total, 12014.8 free, 273.2 used. 501.7 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1 root 20 0 8940 308 268 S 0.0 0.0 0:00.20 init
6 root 20 0 8940 220 180 S 0.0 0.0 0:00.01 init
7 user1 20 0 18080 3456 3348 S 0.0 0.1 0:00.27 bash
72 root 20 0 18924 2900 2800 S 0.0 0.1 0:00.10 sudo
73 root 20 0 18048 2080 2056 S 0.0 0.1 0:00.07 su
74 root 20 0 18076 3608 3516 S 0.0 0.1 0:00.41 bash
366 root 20 0 18444 1784 1324 T 0.0 0.0 0:00.01 top
746 root 20 0 70528 26284 3072 R 0.0 0.6 0:01.24 massif-amd64-li
==746==
15691776
出力15691776は、「top」プロセスのピークメモリ使用量です。
デフォルトでは、Massifはヒープメモリのみを測定します。 ただし、プログラムで使用される all メモリを測定する場合は、— pages-as-heap =yesを使用できます。
Massif は、プロファイリングデータをmassif.outファイルに出力します。 ms_print ツールは、このプロファイリングデータをグラフ化して、プログラムの実行中のメモリ消費量を示します。 また、メモリ割り当てのピーク時に割り当てを担当するサイトに関する詳細情報も表示されます。 次のコマンドを使用して、massif.outファイルのデータをグラフ化できます。
ms_print massif.out
6. その他の最新ツール:HeaptrackとBusybox
Heaptrack は、GUIとテキストの両方のインターフェースを備えたKDEツールです。 フレームグラフとしてピークメモリ使用量を提供します。 Valgrind よりもチェックが少ないため、高速です。
/ proc / [pid] / smaps でPSSの量を追跡するか、 pmap を使用することで、ピークメモリを決定できます。 heaptrackをすでに実行中のプロセスにアタッチすることもできます。
heaptrack --pid $(pid of <your application>)
heaptrack出力は/tmp/heaptrack.APP.PID.gzに書き込まれます。
Busybox は、多くの一般的なUNIXユーティリティの小さなバージョンを1つの小さな実行可能ファイルに結合します。 これは、GNU Coreutils、まで、Linuxなどで通常見られるほとんどのユーティリティの最小限の代替品を提供します。
Busybox は、DebianやUbuntuを含むほとんどのLinuxディストリビューションにプリインストールされています。 最近の多くのディストリビューションにはないコマンドの代わりに使用できます。 同様に、ピークメモリ使用量を知るために、[X58X]-v引数を指定したbusyboxtime実装を使用できます。
$ /usr/bin/time busybox time -v uname -r | grep "Maximum resident set size"
Maximum resident set size (kbytes): 1792
その出力は、GNU time出力に似ています。
7. 結論
この記事では、プロセスのピークメモリ使用量を特定するためのコマンドとツールについて説明しました。
これらのコマンドは、プロセスのメモリ使用率をリアルタイムで視覚化するのに役立ち、必要なアクションを実行できます。 さらに、アプリケーションのメモリ使用量を減らすための測定アクティビティを支援することができます。