スワップランアウェイメモリ使用によるシステムのフリーズ/無応答を防止


48

プロセスが大量のメモリを必要とする場合、システムは他のすべてのプロセスをスワップファイルに移動します。X11サーバーや端末などの必要なプロセスを含むようです。

そのため、プロセスが無制限に割り当てを続けると、そのプロセスがOOMキラーによって強制終了されるまで、すべてが応答しなくなります。私のラップトップは特に賢明で、非常にひどく反応します。マウスカーソルでさえ動かせないプロセスの終了を1時間待ちました。

どうすればこれを回避できますか?

1)スワップを無効にする=>多くのプロセスを開始してから、非アクティブになります。非アクティブなものはスワップに移動する必要があります。

2)SSDを取得する=>高すぎる

3)最大メモリulimit =>を設定しますが、プログラムが適切な大量のメモリを必要とする場合は失敗します。問題は、使用量が多すぎることではなく、他のプロセスを抑制することです。

4)重要なプログラム(X11、bash、kill、top、...)をメモリに保持し、それらを決して交換しない=>これを実行できますか?どうやって?おそらく大きなプログラムだけを交換しますか?

5)?


そして、tiが再び起こりました:( firefoxの実行中にgccを開始し、すべてが30分間ブロックされました。マウスの移動、電子書籍の読み取りなし
-BeniBela

あなたが何を望んでいるのか理解していない。システムが持っているリソースを使って魔法のように高速に処理したいですか?多くのメモリを使用するプロセスをより早く終了させたいですか?
デビッドシュワルツ

本当に必要なのはより多くのRAMのように聞こえます。以下の「非アクティブ」なバックグラウンドタスク。
ダニエルB

2
Alt + SysRq + Fキーの組み合わせを使用して、OOM-killerを強制的に実行できます。これにより、システムがコンソールを開くのを待つのに必要な時間を節約でき、プロセスを強制終了できます。
hololeap

間違っているが、この問題は、システムが存在すべきであるが存在しない(スワップパーティションが小さすぎる)ディスクスワップスペースをシステムが探しているように聞こえる場合は修正してください。十分なスワップスペースがないと、システムはハードドライブ(またはssd)を「スラッシング」して使用可能なスペースを探します。
mchid

回答:


45

TL; DR

短い一時/回答

  • 最も簡単:スワップパーティションを小さくし、低速のストレージからプロセスを実行することでメモリの制限がないという嘘に追いつくカーネルを避けます。
    • 大きなスワップでは、OOM(out of memory manager)はすぐにアクションを実行しません。通常、仮想メモリに基づいて説明され、過去の経験では、スワップ全体がいっぱいになるまで物を殺しませんでした。したがって、スラッシングとクロールのシステムは...
  • 休止状態に大きなスワップが必要ですか?
    • 試行/問題:いくつかのulimitsを設定します(例:をチェックulimit -vし、のasオプションを使用してハードまたはソフトの制限を設定しますlimits.conf)。これは以前は十分に機能していましたが、WebKitを導入したおかげでgigacage、多くのgnomeアプリは無制限のアドレススペースを期待して実行できなくなりました!
    • 試行/問題:オーバーコミットポリシーと比率はsysctl vm.overcommit_memory、これを管理および軽減しようとする別の方法です(たとえば、sysctl vm.overcommit_ratioこのアプローチはうまくいきませんでした。
    • 難しい/複雑な:最も重要なプロセス(例えばssh)にcgroup優先度を適用してみてください。しかし、これは現在cgroup v1にとって扱いにくいようです(願わくばv2でもっと簡単になります)...

私も見つけました:

長期的なソリューション

いくつかのアップストリームパッチが安定したディストリビューションカーネルに入るのを待ちます。また、ディストリビューションベンダーがカーネルのデフォルトをより適切に調整し、systemd cgroupを活用してデスクトップエディションのGUIの応答性を優先することを期待します。

興味のあるパッチ:

だから、悪いのはユーザースペースのコードやディストリビューションの設定/デフォルトだけではありません-カーネルはこれをうまく処理できます。

すでに検討されているオプションに関するコメント

1)スワップを無効にします

少なくとも小さなスワップパーティションを用意することをお勧めします(最新のシステムでは本当にスワップが必要ですか?)。スワップを無効にすると、未使用ページのスワップアウトが防止されるだけでなく、メモリを割り当てるためのカーネルのデフォルトのヒューリスティックオーバーコミット戦略にも影響する可能性があります(Overcommit_memoryのheuristics = 0はどういう意味ですか?)。スワップがなくても、オーバーコミットはおそらくヒューリスティック(0)モードまたは常時(1)モードで機能しますが、スワップなしとネバー(2)オーバーコミット戦略の組み合わせは恐ろしい考えです。そのため、ほとんどの場合、スワップはパフォーマンスを低下させません。

たとえば、一度限りの作業のために最初はメモリにアクセスした後、そのメモリの解放に失敗してバックグラウンドを実行し続ける長時間実行プロセスについて考えます。プロセスが終了するまで、カーネルはそのためにRAMを使用する必要があります。スワップなしでは、カーネルは実際にRAMを積極的に使用したい何かのためにそれをページアウトすることはできません。また、いくつの開発者が怠け者であり、使用後にメモリを明示的に解放しないかを考えます。

3)最大メモリulimitを設定する

これはプロセスごとにのみ適用され、おそらくシステムが物理的に持っているより多くのメモリをプロセスが要求するべきではないという合理的な仮定です!そのため、たった1つのクレイジーなプロセスがスラッシングをトリガーするのを止めながら、寛大に設定することはおそらく有用です。

4)重要なプログラム(X11、bash、kill、top、...)をメモリに保持し、それらをスワップしない

良いアイデアですが、それらのプログラムは積極的に使用していないメモリを独占します。プログラムが適度な量のメモリのみを要求する場合は、許容される場合があります。

systemd 232リリースでは、これを可能にするいくつかのオプションが追加されました。「MemorySwapMax = 0」を使用して、sshのようなユニット(サービス)がメモリをスワップアウトするのを防ぐことができると思います。

それにもかかわらず、メモリアクセスに優先順位を付けることができる方が良いでしょう。

長い説明

Linuxカーネルはサーバーワークロード用に調整されているため、GUIの応答性は悲しいことに副次的な懸念事項です。Ubuntu16.04 LTSのデスクトップエディションのカーネルメモリ管理設定は、他のサーバーエディションと変わらないようです。サーバーとして通常使用されるRHEL / CentOS 7.2のデフォルトと一致します。

OOM、ulimit、および応答性のための整合性のトレードオフ

スワップスラッシング(メモリのワーキングセット、つまり特定の短い時間フレームで読み書きされるページが物理RAMを超えるとき)は常にストレージI / Oをロックします-カーネルウィザードはプロセスを強制終了せずにこれからシステムを保存できませんまたは2 ...

最近のカーネルでLinux OOMの調整が行われ、このワーキングセットが物理メモリの状況を超えており、プロセスを強制終了することを認識しています。そうでない場合、スラッシングの問題が発生します。問題は、大きなスワップパーティションでは、カーネルがコミットを十分に超過し、メモリ要求を処理している間、システムにまだヘッドルームがあるように見えることがありますが、ワーキングセットがスワップにあふれて、ストレージを効果的に処理しようとする可能性がありますそれはRAMです。

サーバー上では、スラッシングによるパフォーマンスのペナルティを受け入れますが、それは決定的な低速でデータを失わないでください。デスクトップでは、トレードオフが異なり、ユーザーは、物事の応答性を保つために、少しのデータ損失(プロセスの犠牲)を好むでしょう。

これはOOMについての素晴らしいコミカルな類推でしたoom_pardon、別名私のロックを殺さないでください

ちなみに、OOMScoreAdjustより重要と見なされるOOMの強制終了プロセスを軽減し回避するためのもう1つのsystemdオプションです。

バッファリングされたライトバック

バックグラウンドライトバックを吸わないようにする」ことは、RAMを占有するプロセスが別のスワップアウト(ディスクへの書き込み)を引き起こし、ディスクへの一括書き込みがIOを必要とする他のすべてを停止させる問題を回避するのに役立つと思います。これはスラッシングの問題自体の原因ではありませんが、応答性の全体的な低下につながります。

制限の制限

ulimitの問題の1つは、アカウンティングが仮想メモリアドレススペースに適用されることです(これは、物理スペースとスワップスペースの両方を組み合わせることを意味します)。としてman limits.conf

       rss
          maximum resident set size (KB) (Ignored in Linux 2.4.30 and
          higher)

したがって、物理RAMの使用量にのみ適用するようにulimitを設定することは、もはや使用可能に見えません。したがって

      as
          address space limit (KB)

唯一の尊敬されている調整可能パラメータのようです。

不幸なことに、WebKit / Gnomeの例で詳しく説明しているように、仮想アドレススペースの割り当てが制限されている場合、一部のアプリケーションは実行できません。

cgroupsは将来役立つでしょうか?

現在、面倒ですが、いくつかのカーネルcgroupフラグを有効にすることは可能です cgroup_enable=memory swapaccount=1(たとえばgrub configで)、cgroupメモリコントローラーを使用してメモリの使用を制限することができます。

cgroupには、「ulimit」オプションよりも高度なメモリ制限機能があります。CGroup v2は、ulimitsの機能を改善する試みのヒントを示しています。

メモリーとスワップを組み合わせたアカウンティングと制限は、スワップ空間の実際の制御に置き換えられます。

CGroupオプションは、systemdリソース制御オプションを介して設定できます。例えば:

  • メモリ高
  • MemoryMax

他の便利なオプションは

  • IOWeight
  • CPUShares

これらにはいくつかの欠点があります。

  1. オーバーヘッド。現在のdockerのドキュメントでは、1%の余分なメモリ使用と10%のパフォーマンス低下について簡単に言及しています(おそらくメモリ割り当て操作に関して-実際には指定していません)。
  2. Cgroup / systemdのものは最近大幅に作り直されたため、アップストリームの流動性はLinuxディストリビューションベンダーが最初に解決するのを待っている可能性があることを意味します。

cgroup v2では、彼らはそれが示唆memory.highスロットルに良い選択肢とプロセスグループでメモリ使用量を管理する必要があります。ただし、この引用は、メモリ不足の状況を監視するには、さらに作業が必要であることを示唆しています(2015年時点)。

ワークロードがより多くのメモリを必要とするかどうかを判断するには、メモリ不足の測定値-メモリ不足によりワークロードがどれだけ影響を受けているかが必要です。残念ながら、メモリプレッシャーモニタリングメカニズムはまだ実装されていません。

systemdとcgroupのユーザースペースツールは複雑であるため、適切なものを設定してこれをさらに活用する簡単な方法は見つかりませんでした。Ubuntuのcgroupとsystemdのドキュメントはあまり良くありません。将来の作業は、デスクトップエディションを備えたディストリビューションがcgroupとsystemdを活用し、高いメモリのプレッシャーの下で、sshとX-Server /ウィンドウマネージャーコンポーネントがCPU、物理RAM、ストレージIOへの優先順位の高いアクセスを取得して、プロセスとの競合を回避することです忙しいスワッピング。カーネルのCPUおよびI / O優先機能は、しばらく前から存在していました。不足しているのは、物理RAMへの優先アクセスのようです。

ただし、CPUとIOの優先順位さえ適切に設定されていません!?systemdのcgroupの制限、適用されたcpuの共有などを確認したとき、私が知る限り、Ubuntuは事前に定義された優先順位を付けていませんでした。例えば、私は走った:

systemctl show dev-mapper-Ubuntu\x2dswap.swap

それをssh、samba、gdm、nginxの同じ出力と比較しました。GUIやリモート管理コンソールなどの重要なものは、スラッシングが発生したときに他のすべてのプロセスと同等に戦わなければなりません。

16GB RAMシステムのメモリ制限の例

休止状態を有効にしたかったので、大きなスワップパーティションが必要でした。したがって、ulimitsなどで軽減しようとしています。

限界

私が入れ* hard as 16777216/etc/security/limits.d/mem.conf単一のプロセスが物理的に可能であるよりも多くのメモリを要求することが許されないであろうというように。スラッシングをすべて防ぐことはできませんが、貪欲なメモリ使用またはメモリリークのある単一のプロセスだけでスラッシングが発生する可能性があります。たとえばgnome-contacts、Exchangeサーバーからグローバルアドレス一覧を更新するなどのありふれた作業を行うと、8 GB以上のメモリを消費します。

RAMを噛むGnomeコンタクト

で見られるように ulimit -S -v、多くのディストリビューションではこのハードとソフトの制限を「無制限」に設定しています。理論的には、プロセスは大量のメモリを要求することができますが、サブセットを積極的に使用するだけで、24GBのRAMが与えられていると喜んで実行されますシステムには16GBしかありません。上記のハード制限により、カーネルが貪欲な投機的メモリ要求を拒否すると、正常に実行できた可能性のあるプロセスが中止されます。

ただし、gnomeの連絡先などの異常なものもキャッチし、デスクトップの応答性を失う代わりに、「空きメモリが不足しています」というエラーが表示されます。

ここに画像の説明を入力してください

アドレス空間(仮想メモリ)のulimitを設定する複雑さ

残念ながら、仮想メモリは無限のリソースであると偽装したい開発者もいます。仮想メモリにulimitを設定すると、一部のアプリが破損する可能性があります。たとえば、WebKit(一部のgnomeアプリが依存します)は、異常gigacageな量の仮想メモリを割り当てようとするセキュリティ機能を追加しました。回避策、FATAL: Could not allocate gigacage memoryMake sure you have not set a virtual memory limitGIGACAGE_ENABLED=noセキュリティ上の利点はありませんが、同様に、仮想メモリの割り当てを制限することはセキュリティ機能もありません(たとえば、サービス拒否を防ぐことができるリソース制御)。皮肉なことに、ギガケージとgnomeの開発者の間では、メモリ割り当ての制限自体がセキュリティ管理であることを忘れているようです。悲しいことに、gigacageに依存しているgnomeアプリは、より高い制限を明示的に要求することに煩わされていないことに気付きました。

公平に言うと、カーネルが仮想メモリの代わりに常駐メモリの使用に基づいてメモリ割り当てを拒否できるようになった場合、仮想メモリが無制限であると装う方が危険は少なくなります。

オーバーコミット

アプリケーションがメモリアクセスを拒否され、オーバーコミットを停止したい場合は、以下のコマンドを使用して、メモリの負荷が高い場合のシステムの動作をテストします。

私の場合、デフォルトのコミット率は次のとおりです。

$ sysctl vm.overcommit_ratio
vm.overcommit_ratio = 50

ただし、ポリシーを変更してオーバーコミットを無効にし、比率を適用する場合にのみ完全に有効になります

sudo sysctl -w vm.overcommit_memory=2

この比率は、全体で24GBのメモリしか割り当てられないことを暗示しています(16GB RAM * 0.5 + 16GB SWAP)。そのため、おそらくOOMが表示されることは決してなく、事実上、プロセスがスワップでメモリに絶えずアクセスする可能性は実質的に低くなります。しかし、システム全体の効率も犠牲にする可能性があります。

開発者がメモリ割り当て要求を拒否するOSを適切に処理しないことが一般的であるため、これにより多くのアプリケーションがクラッシュします。これは、スラッシング(ハードリセット後にすべての作業が失われる)によりロックアップが引き出されることのあるリスクを、さまざまなアプリがクラッシュするより頻繁なリスクとトレードオフします。私のテストでは、システムがメモリ不足に陥り、メモリを割り当てることができなかったときにデスクトップ自体がクラッシュしたため、あまり役に立ちませんでした。ただし、少なくともコンソールとSSHは引き続き機能しました。

VMのオーバーコミットメモリの動作について詳しくはこちらをご覧ください。

sudo sysctl -w vm.overcommit_memory=0デスクトップのグラフィカルスタック全体とその中のアプリケーションがそれでもクラッシュすることを考えると、このためにデフォルトに戻すことを選択しました。


3
これは私がこの問題で見た中で最高の記事であり、「RAMを追加購入するだけ」ではありません。言及していないことの1つは、カーネル構成オプションがこれにどのように影響するかです。たとえば、使用されるプリエンションモデルまたは使用されるI / Oスケジューラは、これに大きな影響を与えますか?
hololeap

2
but the kernel won't be able to use an overcommit strategy for allocating memory and this will likely hurt performance. Even a smaller swap partition allows this. これに対する証拠はありますか?私は、カーネルオーバーコミットはうまくスワップせずに構成されたと考えている
ygrek

@ygrek、ありがとう、言葉遣いはかなり間違っているようです-オーバーコミットしないモード(2)が選択されていない限り、オーバーコミットはスワップなしでも動作します。デフォルトのヒューリスティックオーバーコミットモード(0)、または常にコミット(1)モードは、おそらくスワップなしでも動作します。スワップをオフにすると、オーバーコミットコードがメモリを割り当てることができなくなります(そして、どのモードが特に影響を受けたのか)。運がなくても再びGoogleを検索しましたが、これは半有用な投稿でした。stackoverflow.com/ questions / 38688824 / …答えを適切に編集します。
-JPvRiel

バックグラウンドのライトバックパッチが役立つことを期待していましたが、非常に新しいカーネル(4.14.81)を使用しており、重いディスクI / Oでかなりの応答性の問題に直面しています(スワップが原因かどうかに関係なく)。デバイスマネージャーまたはLUKS暗号化が何らかの理由でパフォーマンスの問題を引き起こしているのだろうか。私はこの種の問題をデバッグする方法をほとんど手がかりがありません。
ダリウスジャハン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.