GNU/Linux >> Linux の 問題 >  >> Ubuntu

コマンドラインからOom-killerをテストする方法は?

OOMキラー またはメモリ不足キラー
linux カーネルは、システムのメモリが非常に少ない場合に使用します。 …これにより、プロセスに割り当てられた
メモリがアクティブに使用されていることを確認することで、システムメモリを最大限に活用できます。

この自己回答の質問は尋ねます:

  • コマンドラインからoom-killerをテストする方法は?

自己回答にかかる30分よりも速い方法が受け入れられます。

承認された回答:

OOMキラーをすばやくトリガーするための鍵は、ディスクアクセスによって行き詰まらないようにすることです。だから:

  1. スワップを使用する場合のOOMの動作をテストすることが特に目的でない限り、スワップは避けてください。 テストの前にスワップを無効にし、後で再度有効にすることができます。 swapon -s 現在有効になっているスワップを示します。 sudo swapoff -a すべてのスワップを無効にします。 sudo swapon -a 通常、それらを再度有効にするには十分です。

  2. 非スワップディスクアクセスによるメモリアクセスの散在は避けてください。 そのグロビングベースの方法は、最終的には使用可能なメモリを使い果たします(ファイルシステムに十分なエントリがある場合)が、大量のメモリが必要な理由は、ファイルシステムにアクセスして取得した情報を格納するためです。 SSDを使用している場合でも、スワップがオフになっている場合でも、ディスクからの読み取りに多くの時間が費やされる可能性があります。特に、ディスクアクセスが散在するメモリアクセスのOOM動作をテストすることが目標である場合、その方法は合理的であり、おそらく理想的ですらあります。そうでなければ、あなたははるかに速くあなたの目標を達成することができます。

スワップを無効にすると、物理ディスクからほとんど読み取らないメソッドは非常に高速になります。これには、 tail /dev/zeroが含まれます (falstaffによって発見され、Doug Smythiesによって上記でコメントされました)。キャラクターデバイス/dev/zeroから読み取りますが 、その「デバイス」はnullバイト(つまり、すべてゼロのバイト)を生成するだけで、デバイスノードが開かれると物理ディスクアクセスを必要としません。 tailであるため、この方法は機能します 入力で末尾の行を探しますが、ゼロのストリームには改行文字が含まれていないため、破棄する行を取得することはありません。

アルゴリズムでメモリを割り当ててデータを取り込む、解釈された言語のワンライナーを探しているなら、幸運です。ほぼすべての汎用解釈言語では、他の方法で使用しなくても、大量のメモリを割り当てて書き込むのは簡単です。これは、tail /dev/zeroとほぼ同じ速さのPerlワンライナーです。 (私はそれを広範囲にベンチマークしていませんが):

perl -wE 'my @xs; for (1..2**20) { push @xs, q{a} x 2**20 }; say scalar @xs;'

4 GiBのRAMを搭載した古いマシンでスワップをオフにすると、それとtail /dev/zero 実行するたびに約10秒かかりました。どちらも、それよりもはるかに多くのRAMを搭載した新しいマシンで正常に動作するはずです。あなたはそのperlを作ることができます 目標が簡潔である場合は、コマンドをはるかに短くします。

そのPerlワンライナーは繰り返し生成します(q{a} x 2**20 )適度に長い文字列(それぞれ約100万文字)を分離し、配列(@xs)に格納することですべての文字列を保持します )。テスト用に数値を調整できます。使用可能なすべてのメモリを使用しない場合、ワンライナーは作成された文字列の総数を出力します。 OOMキラーがperlを殺すと仮定すると –上記の正確なコマンドを使用し、邪魔になるリソースクォータがない場合、実際には常にそうなると思います。その場合、シェルはKilledを表示する必要があります。 。次に、他のOOMの状況と同様に、dmesg 詳細があります。

関連:DVT(設計検証テスト)チェックリストには何を含める必要がありますか?

私はその方法が好きですが、Doug Smythiesの回答にあるような、Cプログラムの作成、コンパイル、および使用に関して役立つ何かを示しています。メモリの割り当てとメモリへのアクセスは、高レベルの解釈された言語では別々のことのようには感じられませんが、Cでは、それらの詳細に気づき、必要に応じて調査することができます。

最後に、OOMキラーが実際にプログラムを殺したものであることを常に確認する必要があります 。確認する1つの方法は、dmesgを検査することです。 。一般に信じられていることとは反対に、Linuxでも、メモリを割り当てようとするとすぐに失敗する可能性があります。明らかに失敗する巨大な割り当てでこれを実現するのは簡単です…しかし、それらでさえ予期せずに発生する可能性があります。そして、一見合理的な割り当てはすぐに失敗する可能性があります。たとえば、私のテストマシンでは、perl -wE 'say length q{a} x 3_100_000_000;' 成功し、perl -wE 'say length q{a} x 3_200_000_000;' プリント:

Out of memory!
panic: fold_constants JMPENV_PUSH returned 2 at -e line 1.

どちらもOOMキラーをトリガーしませんでした。より一般的に言えば:

  • プログラムが必要なメモリ量を事前に計算し、1回の割り当てでそれを要求した場合、割り当ては成功する可能性があります(成功した場合、十分なメモリが使用されている場合、OOMキラーはプログラムを強制終了する場合と強制終了しない場合があります)。または、割り当てが単に失敗する可能性があります。
  • 配列に非常に多くの要素を追加して配列を膨大な長さに拡張すると、実際にはOOMキラーがトリガーされることがよくありますが、確実に テストでは驚くほどトリッキーです。これを行う方法は、ほとんどの場合、最も効率的な方法であるため、容量が xの新しい各バッファーを作成することです。 古いバッファの容量の倍。 xの一般的な値 1.5と2を含みます(この手法は「テーブルダブリング」と呼ばれることがよくあります)。これにより、実際に割り当てて使用できるメモリの量と、カーネルが認識している量との間のギャップを埋めることができます。
  • メモリの割り当ては、カーネルや実際に使用可能なメモリの量とはほとんど関係がなく、OOMキラーをトリガーしないという理由で失敗する可能性があります。特に、プログラムは、非常に多数の小さな割り当てを正常に実行した後、任意のサイズの割り当てで高速に失敗する可能性があります。この失敗は、プログラム自体によって実行される簿記で発生します。通常は、malloc()などのライブラリ機能を介して実行されます。 。 bashを使用したテスト中に、これが今日私に起こったことだと思います。 配列(実際には二重にリンクされたリストとして実装されています)、bash 9バイトの割り当てというエラーメッセージで終了します 失敗しました。

OOMキラーは、意図的にトリガーするよりも、誤ってトリガーする方がはるかに簡単です。

意図的にOOMキラーをトリガーしようとする場合、これらの問題を回避する1つの方法は、メモリを要求しすぎることから始めて、Doug SmythiesのCプログラムのように、徐々に小さくすることです。もう1つの方法は、適度なサイズのメモリのチャンク全体を割り当てることです。これは、上記のPerlワンライナーが行うことです。100万文字の文字列(および舞台裏での追加のメモリ使用量)は特に負担になりません。しかし、まとめると、1メガバイトの購入はすべて合計されます。


Ubuntu
  1. コマンドラインからディスク使用量を取得する方法は?

  2. コマンドラインからミュートする方法は?

  3. コマンドラインから明るさ、色、シャープネスを変更するにはどうすればよいですか?

  1. コマンドラインからGvfsマウントにアクセスする方法は?

  2. コマンドラインでスクリプトから関数を実行するにはどうすればよいですか?

  3. コマンドラインからdmesgに書き込むにはどうすればよいですか?

  1. Ubuntuのコマンドラインからセキュリティアップデートをインストールする方法

  2. コマンドラインからHdmiへのオーディオ出力を変更するにはどうすればよいですか?

  3. コマンドラインから IP アドレスを取得するにはどうすればよいですか?