Linuxの応答性、メモリ、およびページングを飼いならす方法


27

オーバーフローに関する最初の質問=)... +100バウンティ。今まで本当に気にかけていたことは考えられませんでした。

Linuxデスクトップの応答性の状態、たとえばhttp://brainstorm.ubuntu.com/item/85/に本当にうんざりしている-空きRAMが少ない状況、またはディスクスループットが高い状況では、システムが遅くなります。クロール ; これはまともなパフォーマンスを必要とするアプリケーションにとって絶対にひどいものです。さらに、UIは完全に応答しません。たとえば、アプリケーションがリソースを占有している場合、オプションを押して強制終了することができますが、Linuxではデスクトップをalt-tabまたは切り替えたり、ctrl-alt-f1でさえ取得することはできませんターミナル-できます。1回の操作で約1〜2分かかります。

gkrellmを使用するので、展開の状況を確認できます。通常、メモリ使用率がかなり高くなるか、ディスクのスループットが劇的にジャンプします。

2.6GHzクアッドコアと4GBの800MHz DDR2 RAMを搭載したハードウェアは悪くありません(6GBが必要でしたが、ハードウェアの非互換性により、古いセットとの組み合わせはできませんでした)。必然的にRAMを増やすと、この問題はなくなるかもしれませんが、それが問題の核心だとは思いません。異なるディスクに2つのスワップパーティションもあります。

問題は3つあると感じています。

  • 大量のメモリを消費する暴走プログラム-これらのプログラムには法律が定められていなければならず、
    • (たとえば、Chromeのタブは、それぞれ20〜50MBで、一部は数百MBを使用できます)
    • (たとえば、update-dbやインデクサーのような他のプログラムは、実行するたびにシステムのクロールが遅くなるため、cronを無効にして削除する必要がありました。)
  • カーネルまたはバス競合で何らかのひどいことが起こり、ディスクスループットの高い状況がシステム全体のクロールを遅くする(おそらく重要なプログラムをページアウトすることにより)
  • カーネルは、メモリ、ページング、プロセッサ使用率などのリソースの観点からUIや重要なプログラムを優先していません。

賛成票:

したがって、このようなプログラムがすべてなくなる解決策を探しています。特に、システムや他のプログラムが完全に影響を受けず、手動で何かを手動で殺すのに十分な長さでありながら、プロセスが比例して遅くなるようなソリューションを探しています。また、ウィンドウマネージャープロセス(およびUIの応答性に影響する可能性のあるもの)は、すべての状況で応答する必要があります。

特に/etc/security/limits.confman limits.conf)に興味をそそられますが、これはユーザーごとの制御を与えるだけであり、ファイル内のコメントされた例は説明やどこから始めるかという点でかなり不透明に見えます。私はlimits.confうまくいくことを望んでいますが、うまくいかなかったとしても、それが私の問題の適切な解決策でなかったとしても、私が達成しようとしているほどきめ細かくても驚かないでしょう。limits.confまた、limits.confが機能すると仮定して、プロセス名ごとが理想的です。この時点ですべての解決策を受け入れていますが、人々が提供するlimits.confを試して、それが機能するかどうかをテストして喜んでいます。

OS Xがこのような優れたUIの応答性を維持するためにどのように管理するかについての洞察を得ることが役立つ場合もあります。

既に/tmpフォルダとキャッシュフォルダを調整してオンにしていますがtmpfs、一般的にディスク使用率はほぼゼロです。

漠然とした関連トピック:

  • メモリオーバーコミット

私はうまくいかないと思う答え:

  • swapoff (これにより、メモリホグプログラムは殺人で逃げることができ、メモリが本当に悪い場合はシステムが永久にフリーズします。特定のプログラムをスワップしてターゲットにする前にOOM-killerを起動する調整を提案できる人に賛成票を投じます)
  • echo ?? > /sys/.../swappiness (認識できる効果なし)
  • nice (働いたことがない)
  • ionice (違いに気付いたことはありません)
  • selinux(プログラムの非互換性は悪夢のようです)
  • リアルタイムlinux、つまりカーネルを中断することができます(カスタムカーネルのコンパイルと更新に対処したくない。リポジトリに移行した場合は問題ないかもしれない)
  • *

うーん、私は賞金を置くことができないようです。リンクが48時間表示されないのではないかと思います......それでは、私が獲得したすべての評判で賞金を投稿します
user76871

1
+1、これは私がLinuxデスクトップに関して日々抱えている最大の問題です。たぶん数週間に一度、時々フリーズしますが、それは特にイライラするほどではありません。ただし、先ほど言ったように、IOの使用率が高いアプリケーションの問題であるようです。CPUの使用率が高いアプリケーションは、一般的なシステムパフォーマンスにほとんど影響しません。ioniceを知らなかった、それが適切に動作する場合、それはこの問題の正しい解決策になるようです。
crazy2be

1
3年後、これはまだLinuxの問題です。@ crazy2beまたはuser76871、その間に解決策を見つけたとは思いませんか?
グルタニメート

@Glutanimate:はい、32GBの物理RAMとそれ以下(まあ、16GBかもしれません...でもそれはそれを押し上げています)、また大容量のビデオRAMです。これは、CPUの高さや割り込み、その他の理由で応答しないことを修正しませんが、メモリ不足の状況で応答しないことを防ぎます。
user76871

回答:


6

システムがヘビースワッピングに入るように聞こえます。を使用vmstat 1すると、詳細が明らかになる場合があります-ターミナルウィンドウで実行し、スローダウンが開始されたときに切り替えます。

/ tmpと「キャッシュ」をtmpfsに入れるのではなく、noatimeオプションでマウントされた通常のディスクファイルシステムを使用します。多くの場合、使用されたデータはキャッシュにとどまり、古いデータをディスクに書き込んで、アプリケーション用にRAMを解放できます。/ tmpやキャッシュが大きくなれば、これは大いに役立つかもしれません。


1
言及する場合は+1 noatime
ローレンス

言及していただきありがとうございますnoatime、残念ながら私はそのマウントオプションを使用していましたが、応答性を確保するのにあまり役に立たなかったと思います(ただし、ディスクが過負荷にならないようにするのに役立ちます); 現在の設定でnoatimeを再度有効にしていることを確認してください。noatimeで非tmpfsを使用するのは少し奇妙に思えますが、それは大量の書き込みが発生することをまだ想像しているからです。
-user76871

+1、試行済みvmstat 1-スワップが実際に問題の大きな部分であるという診断をクリンチするのに非常に役立ちます
-user76871

2
痛い。このような重いスワッピングを必要とするLinuxシステムを見たことはありません。df -mtmpfsファイルシステムで使用されているメモリの量を確認しましたか?RAMを比較的速く消費しているものがあります。
ターボJ

提案と-mオプションについて教えてくれてありがとう。残念なことにdf -h -m、メモリが100 MBしかないことを示しているように見えるtmpfsので、tmpfsとキャッシュにメモリを使用することに関係があるのではないかと思います。これも珍しいことではないようです。複数のディストリビューションでRAMが限界に近づいたときに発生しました。
-user76871

5

私はカーネル開発者ではありませんが、この問題に何度も遭遇したので、この問題に何年も哲学を費やしました。私は実際に全体の状況の比phorを思いついたので、それを教えてください。私の話では、「スワップ」のようなものは存在しないと仮定します。とにかく、最近の32 GB RAMではスワップはあまり意味がありません。

水がパイプを介して各建物に接続され、町が能力を管理する必要があるあなたの近所を想像してください。1秒間に100単位の水しか生産していないと仮定しましょう(そして、貯水タンクがないため、未使用の容量はすべて無駄になります)。各家(家=小さなアプリ、端末、時計ウィジェットなど)には、1秒間に1ユニットの水が必要です。あなたの人口は90人なので、誰もが十分な水を得ることができるので、これはすべて良いことです。

今、市長(=あなた)は、大きなレストラン(=ブラウザー)を開くことを決定します。このレストランには複数の料理人(=ブラウザータブ)があります。各料理人は毎秒1ユニットの水を必要とします。10人の料理人から始めるので、近所全体の総水消費量は100単位の水であり、それでも十分です。

今、楽しいものが始まります:あなたはレストランに別のコックを雇います。あなたは何かをする必要があります。

水管理(=カーネル)には3つのオプションがあります。

1.最初のオプションは、最近水を使用しなかった家のサービスを単に切断することです。これは問題ありませんが、接続されていない家が再び水を使用したい場合、彼らは再び長い登録プロセスを経る必要があります。管理者は、複数の家を切断して、より多くの水資源を解放できます。実際、彼らは最近水を使用しなかったすべての家の接続を切断し、その結果、ある程度の無料の水を常に利用可能にします。

あなたの町は機能し続けていますが、マイナス面は進歩が止まってしまうことです。あなたの時間のほとんどは、サービスを回復するために水管理を待つことに費やされます。

これは、カーネルがファイルバックアップページで行うことです。大きな実行可能ファイル(クロムなど)を実行すると、そのファイルがメモリにコピーされます。メモリが少ない場合、または最近アクセスされていない部分がある場合、カーネルはそれらをディスクからリロードできるため、それらの部分をドロップできます。これが過度に行われると、すべてがディスクIOを待機するため、デスクトップが停止します。また、多くのIOを実行し始めると、カーネルは最近使用したページの多くをドロップします。これが、DVDイメージのようないくつかの大きなファイルをコピーした後、バックグラウンドアプリに切り替えるのに時間がかかる理由です。

これは私にとって最も厄介な動作です。なぜなら、私は接続を嫌い、あなたはそれを制御することができないからです。スイッチをオフにできると便利です。私はの線に沿って何かを考えています

sed -i 's/may_unmap = 1/may_unmap = (vm_swappiness >= 0)/' mm/vmscan.c

そして、vm_swappinessを-1に設定してこれを無効にすることができます。これは私の小さなテストでは非常にうまくいきましたが、残念ながら私はカーネル開発者ではないので、誰にも送信しませんでした(そして明らかに、上記の小さな変更は完全ではありません)。

2。管理者は、新しい料理人の水に対する要求を拒否する可能性があります。これは最初は良いアイデアのように聞こえます。ただし、2つの欠点があります。まず、それらを使用していないにもかかわらず、多くの水契約を要求する会社があります。これを行う1つの考えられる理由は、余分な水が必要な場合に水管理者と話をするオーバーヘッドをすべて回避することです。彼らの水の使用量は、一日の時間に応じて上下します。たとえば、レストランの場合、会社は真夜中に比べて正午にずっと多くの水を必要とします。したがって、彼らは使用する可能性のあるすべての水を要求しますが、それは深夜に水配分を無駄にします。問題は、すべての企業がピーク時の使用量を正確に予測できるわけではないため、より多くの要求を心配する必要がなくなることを期待して、はるかに多くを要求することです。

これは、Javaの仮想マシンが行うことです。起動時に大量のメモリを割り当て、それから動作します。デフォルトでは、カーネルは、Javaアプリが実際に使用を開始したときにのみメモリを割り当てます。ただし、オーバーコミットを無効にすると、カーネルは予約を真剣に受け止めます。実際にリソースを持っている場合にのみ、割り当てが成功します。

ただし、このアプローチにはもう1つ、より深刻な問題があります。ある会社が毎日10単位ではなく、1ユニットの水を要求し始めたとします。最終的には、空きユニットが0の状態になります。これで、この会社はこれ以上割り当てることができなくなります。とにかく大企業を気にする人は大丈夫です。しかし問題は、小さな家でもより多くの水を要求できないことです!突然の観光客の流入に対処するために、小さな公衆トイレを建設することはできません。近くの森林の火災に緊急用の水を提供することはできません。

コンピューター用語:オーバーコミットのない非常に低いメモリの状況では、新しいxtermを開くことができず、マシンにsshすることも、検索するための新しいタブを開くこともできません修正。つまり、オーバーコミットを無効にすると、メモリ不足のときにデスクトップが使用できなくなります。

3.ここで、企業が水を使いすぎたときに問題を処理する興味深い方法を紹介します。水管理はそれを爆破します!文字通り:レストランのサイトに行き、ダイナマイトを投げ入れ、爆発するまで待ちます。これにより、町の必要水量が一気に減り、新しい人が入居できるようになり、公衆トイレなどを作ることができます。たとえば、すでに多くの人が入っている場合はレストランに行かないように人々に伝えます(たとえば、ブラウザのタブを少なくします)。

これは実際、カーネルがすべてのオプションを使い果たしたときにカーネルが行うことであり、メモリが必要です。OOMキラーを呼び出します。(多くのヒューリスティックに基づいて)大規模なアプリケーションを選択して強制終了し、大量のメモリを解放しますが、応答性の高いデスクトップを維持します。実際、Androidカーネルはこれをさらに積極的に実行します。メモリが少ないときに、最後に使用したアプリを強制終了します(最後の手段としてのみ行うストックカーネルと比較して)。これは、Androidではバイキングキラーと呼ばれます。

これは問題に対する最も簡単な解決策の1つだと思います。これより多くの選択肢があるわけではないので、すぐに解決してください。問題は、OOMキラーの呼び出しを回避するためにカーネルが非常に多くの作業を行う場合があることです。そのため、デスクトップが非常に遅く、カーネルがそれについて何もしていないことがわかります。しかし、幸いなことに、OOMキラーを自分で呼び出すオプションがあります!まず、マジックsysrqキーが有効になっていることを確認し(例echo 1 | sudo tee /proc/sys/kernel/sysrq)、カーネルのメモリが不足していると感じたら、Alt + SysRQ、Alt + fを押します。

それでいいのですが、試してみたいですか?メモリ不足の状況は再現が非常に簡単です。そのための非常にシンプルなアプリがあります。2回実行する必要があります。最初の実行で、使用可能なRAMの量が決まり、2回目の実行でメモリ不足の状況が発生します。このメソッドは、スワップが無効になっていることを前提としていることに注意してください(例:を実行sudo swapoff -a)。コードと使用法は次のとおりです。

// gcc -std=c99 -Wall -Wextra -Werror -g -o eatmem eatmem.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int main(int argc, char** argv)
{
    int limit = 123456789;
    if (argc >= 2) {
        limit = atoi(argv[1]);
    }
    setbuf(stdout, NULL);
    for (int i = 1; i <= limit; i++) {
        memset(malloc(1 << 20), 1, 1 << 20);
        printf("\rAllocated %5d MiB.", i);
    }
    sleep(10000);
    return 0;
}

そして、これがあなたの使い方です:

$ gcc -std=c99 -Wall -Wextra -Werror -g -o eatmem eatmem.c
$ ./eatmem
Allocated 31118 MiB.Killed
$ ./eatmem 31110
Allocated 31110 MiB.Killed

最初の呼び出しは、31,118 MiBの空きRAMがあることを検出しました。そこで、カーネルがメモリを殺すのではなく、ほぼすべてのメモリを使い果たすように、31,110 MiB RAMを割り当てるようアプリケーションに指示しました。私のシステムがフリーズした:マウスポインターでさえ動かなかった。Alt + SysRQ、Alt + fを押すと、eatmemプロセスが強制終了され、システムが復元されました。

メモリ不足の状況で行うオプションを説明しましたが、最善のアプローチは(他の危険な状況と同様に)そもそも回避することです。これを行うには多くの方法があります。私が見た一般的な方法の1つは、システムの残りの部分とは異なるコンテナーに(ブラウザーなどの)動作不良のアプリケーションを配置することです。その場合、ブラウザはデスクトップに影響を与えることはできません。しかし、予防自体は質問の範囲外であるため、これについては説明しません。

TL; DR:現在、ページングを完全に回避する方法はありませんが、オーバーコミットを無効にすることで完全なシステム停止を緩和できます。ただし、メモリ不足の状況ではシステムは使用できませんが、方法は異なります。上記に関係なく、メモリ不足の状況では、Alt + SysRQ、Alt + fを押して、カーネルが選択する大きなプロセスを強制終了します。システムは数秒後に応答性を回復するはずです。これは、マジックsysrqキーが有効になっていることを前提としています(デフォルトでは無効です)。


私はあなたにこのリソースの恩恵としての評判をすべて与えたので、コメントを残すこともできませんでした:)最後に、この素​​晴らしい答えに感謝することを言うためにいくつかを得ました!8GBのラップトップを持っている間は常にこの問題に対処していました(クレイジーですが、当時はシステムが定期的にメモリ不足になっていました)。最近、私はこのプロジェクトを見つけました:github.com/rfjakob/earlyoomは手遅れになる前にいくつかのプロセスを殺すことでシステムのハングを防ぐのに役立つかもしれません
ウラドフロロフ

4

すべての一時ファイルとキャッシュファイルを配置すると、使用可能tmpfsな空きRAMの量が減少するため、システムがこれを使用しない場合よりも早くスワップを開始する可能性があります。

オーバーロードされている何らかのカーネル機能またはドライバーに依存しているアプリケーションがあるようです。ブラウザとインデクサーを使用している以外のアプリケーションの種類、およびインデクサーを無効にしていることについてはあまり詳しく説明しません。

LXDEやIceWMなど、より少ないリソースを消費するデスクトップ環境またはウィンドウマネージャーに切り替えてみてください。職場では、非常に最小限のデスクトップ環境のために、LXDEがインストールされたLinuxシステムとROX-Filerを使用しています。このLinuxシステムの目的は、VMWare Playerを実行して、Windows XPとWindows 7を同時に実行できるようにすることです。それはあなたが言うものと同様のハードウェア仕様であり、ハードウェアを通過させているこの重い負荷の下ではあまり反応性の問題はありません。私は持っていない任意の Linuxでは、それ自体で応答性の問題を(それは時々は私が第二を待たせることを通常のVMだし、これが期待されている2のVM + 1 OS間の1枚のディスクを共有する)、常にいつでも仮想マシンを中断または停止することができましたしたい。

だから私にとっては、あなたが実行している特定のアプリケーションの問題を指摘しています。

ディスクドライブのDMAは有効になっていますか?(使用hdparm)フルディスク暗号化を使用している場合、すべてのディスクトラフィックがCPUを通過する必要があり、DMAの利点の多くが無効になります。その結果、ディスクトラフィックが多いとCPUが急上昇し、システム全体の速度が低下します。(編集:明確にするために、DMAを無効にするか使用dm-cryptすると、ディスクトラフィックが多いときにCPUが高くなります)


2
問題のポイントは、WMが肥大化してシステムが遅くなることではなく(通常の使用では完全に応答する可能性が高い)、メモリが不足して起動する必要があるときにカーネルがアプリケーションを適切に優先順位付けしないことです重いスワップ。私はこれまで使用したすべてのデスクトップLinuxでこの問題を抱えていましたが、軽量のプログラムを使用したり、RAMを追加したりすることは役立つかもしれませんが、問題の根本を解決することはできません。
crazy2be

私の以前の投稿で、私は次のように言った:「あなたは、オーバーロードされているある種のカーネル機能やドライバーに依存しているアプリケーションを持っているようだ。」したがって、ボトルネックは特定のカーネルモジュールにある可能性があります。私はカーネルの専門家ではありませんが、カーネル側、特にモジュール側からのメモリ割り当ては、ユーザーランド側とは異なる動作をしていると確信しています。カーネル側のCPU使用率も異なる方法で処理される可能性があります(カーネルプロセスを「ナイス」にできるかどうかはわかりません)。関連する特定のアプリケーションを知らない限り、これ以上コメントすることはできません。
ローレンス

また、FUSE NTFSを使用している場合、速度が低下する可能性があります。
ローレンス

1
tmpfsなどのRAMベースのファイルシステムは(明らかに)RAMをより速く使い果たし、軽量のWMは根本的な問題の症状をわずかに軽減できることを認識しています。ディスクへの書き込みの応答性が悪いため、tmpfsを使用するようにプレッシャーを感じました。それにもかかわらず、あなたの提案、特にDMAに関する部分に感謝します。これはおそらく関連するトピックのリストに追加しました。記録のために、私はDMAが有効になっていて、暗号化ファイルシステムを使用していないと信じています。
-user76871

1

これは、Linuxのスケジューラの一般的な問題です。IOの負荷が高いアクティビティが発生するたびに、システムの速度が低下してクロールされます。カーネルのハッキングに興味がない限り、状況を改善するためにできることは本当に多くありません:)

多分これらは助けることができます:

http://www.phoronix.com/scan.php?page=article&item=linux_2637_video&num=1

http://www.osnews.com/story/24223/Alternative_to_the_200_Lines_Kernel_Patch_that_Does_Wonders_


1
私が思い出すように、これらのカーネルパッチは、GUIアプリケーションと対話しようとしながら、プログラムをコンパイルするか、ターミナルで非常にCPU(およびIO?)が重い何かを行う場合にのみ関連します。残念ながら、あるGUIアプリケーションがいくつかの重い作業を行っており、別のGUIアプリケーションで作業しようとしている、より一般的な状況では役に立ちません。
crazy2be

0

質問は2年以上前であり、@ ypsuの回答は素晴らしいものですが、RAM不足のためにLinuxベースのシステムが悪化している状況は今も残っています。

問題についての私の観察結果は次のとおりです。たとえスワップがまったくなくても、システムのメモリが不足すると、100%のディスク負荷であるため、ハードドライブインジケータが点灯します。この事実を考えると、根本的な原因は、カーネルがディスクから復元できるものをアンロードすることによってメモリを解放しようとしていることであると思われます。通常、GUIアプリケーションには多数の共有ライブラリがあるため、システムはそれらの一部をアンロードするだけで十分であると考えるかもしれませんが、アンロードされたライブラリを戻す必要がある次のユーザースペース操作までしか機能しません。これは、共有ライブラリのアンロードとそれらの再ロードの無限ループを引き起こす最も可能性の高いシナリオのようです。

手遅れになる前に最もメモリを消費するプロセスを殺すユーザースペースデーモンとして機能するプロジェクトがあります:https : //github.com/rfjakob/earlyoom

また、メモリを大量に消費するアプリケーション(Chromeなど)に対して、メモリの制限が適切なDockerコンテナを使用していました。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.