このメモリの問題をエレガントに解決するには?

このメモリの問題をエレガントに解決するには?

私はスワップパーティションを持つ標準のLinux(Debianテスト)ラップトップを持っています。

私はそれを持ってたくさんの実験をしました。そのうちのいくつかは実際にメモリ集約的であり、Linuxが基本的に動作する方法が私にとって問題になります。

  1. ラップトップの前に座って
  2. 端末を開く
  3. と入力pythonしてからa = [0]*100000000

これで、この大きなリストを処理するのに十分なRAMがない可能性があります。 Linux は RAM を満たしてから交換し、数分後に OOM キラーがトリガされ、(ほぼ)ランダムなサービスを終了します。適切な瞬間にCtrl + Cを押し、python端末にまだフォーカスがある場合は、コンピュータが再び応答します。

不要なスワップを防ぎ、プロセスが私が持っているよりも多くのメモリ(RAM)を割り当てる権限を拒否するために、いくつかのメモリ制限を適用したいと思います。メモリ要件が特定の制限を下回った場合、またはルートから要求されている場合は、ルート以外のユーザーに対して最もメモリを消費するプロセスのみが終了します。

ulimit -Sv [mem]後ろから聞いた!

ほほ! 「使用がcgroups通過しましたcgexec!」最初の行の誰かが言いました!

はい、あなたは正しいです。これは実際には非常に良いソリューションです。しかし:

  • システム全体には適用されません。
  • プロセスごとに制限が設定されます。
  • 制限は静的であり、実際に利用可能なRAM(AFAIK)の量を考慮しません。
  • ここそしてそこ彼らは、これが厳しい制限を強制するための実際の良い解決策ではないと言います。

私が望むのは、カーネルが「あなたはユーザーに属しています」と言うことです。金持ち(ルートではない)メモリを多く使用しており、メモリが不足します。すみません…すぐに地獄に行きます! 」

または:「一体何をするの?あなたは必要です。XMBのみワイMB利用可能。はい、SWAPは空ですが、SWAPを使用して汚れた操作を実行することはありません。そうですか?いいえ、いいえ!あなたの記憶はありません!続けると死ぬ! 」

答え1

誰かがあなたの耳に何かを提案しましたcgroups。さて、次のことができますので、その方向を見てください。

  • 選択したワークセットに適用されます(システム全体ではなくプロセス固有)。
  • このグループに制限が設定されました。
  • 制限は静的です。
  • メモリおよび/またはメモリ+スワップに厳しい制限を適用できます。

これはあなたをもたらすことができます目標に近づく:

group limited {
  memory {
    memory.limit_in_bytes = 50M;
    memory.memsw.limit_in_bytes = 50M;
  }
}

これは、このcgroupの操作は最大50Mメモリ、50Mメモリ+スワップまでしか使用できないため、メモリがいっぱいになるとスワップされませんが、メモリがいっぱいにならないと一部のデータがスワップにマッピングされる可能性があります。許可されます。

これはから抜粋したものです。cgroup メモリー文書:

memsw制限を使用すると、スワップスペースの不足によるシステムOOMを回避できます。

答え2

私はしばしば同じ問題に直面しています。私の一般的なワークフローには、MATLABでの多くの計算が含まれています。時々私は思わず利用可能なメモリ量を超える新しい変数を割り当てようとします。システムがハングし、通常は再度作業するには、コンピュータをハード再起動する必要があります。 :血

私の場合、そしてあなたの状況も同じようです。私はMATLABが使用するメモリの量を静的な量に制限することについてあまり心配しません。私は停止しないマシンに興味があり、喜んでします。システム応答能力を維持するためにMATLABプロセスを犠牲にしてください。

レスポンスからインスピレーションを得るこの投稿、次のスクリプトを作成しました(watch_memory.shと命名しました)。

#!/bin/bash

MONITOR=$(free | grep 'buffers/cache:')
MEM_USED=$(echo $MONITOR | awk '{ print $3 }')
MEM_FREE=$(echo $MONITOR | awk '{ print $4 }')

MEM_PERC=$(( 100*MEM_USED / (MEM_FREE+MEM_USED) ))

while :; do
    if [ "$MEM_PERC" -gt "95" ]
    then
        kill $1
        echo "$1 killed for using too much memory."
        exit
    fi
    sleep 1

    MONITOR=$(free | grep 'buffers/cache:')
    MEM_USED=$(echo $MONITOR | awk '{ print $3 }')
    MEM_FREE=$(echo $MONITOR | awk '{ print $4 }')
    MEM_PERC=$(( 100*MEM_USED / (MEM_FREE+MEM_USED) ))
done

このスクリプトは、毎秒使用可能なメモリの割合を確認します。システムが枯渇すると、「犠牲者」pid(スクリプトに引数として渡されます)が終了します。

スクリプトの優先順位を調整しないと、犠牲者が死ぬのに約10〜20秒かかりましたが、まだ機能しました。負の優先順位でスクリプトを実行すると、違反後すぐに終了します(この例では、11916はメモリが不足している場合は終了しようとしているpidです)。

sudo nice -n -5 bash watch_memory.sh 11916

関連情報