最近の数週間にわたって、プロセスでワンタイムメモリリークが発生し、RHEL 7システムのすべてのメモリが消費されました。
これで、特定の金額を超えないように制限を設定しようとしています。
ulimit -v設定を使用してこの量を設定します(-m設定が機能しないため)。
もしそうなら、これが十分なのか、それとも物理メモリを制限する方法も必要かどうか疑問に思います。それでは、最良のアプローチは何ですか?
仮想メモリが常に物理メモリと一緒に増加する場合、-v自体で十分です。
答え1
動作方法の説明ulimit
:
ulimit
処理済みsetrlimit
そしてgetrlimit
システムコール。 (その一部である)strace
bashプロセスで確認するのは簡単です。私は1024kbを設定しました:ulimit
bash
max memory size
$ ulimit -m 1024
他のコンソールから:
$ strace -p <my_bash_pid>
. . .
getrlimit(RLIMIT_RSS, {rlim_cur=1024*1024, rlim_max=1024*1024}) = 0
setrlimit(RLIMIT_RSS, {rlim_cur=1024*1024, rlim_max=1024*1024}) = 0
. . .
setrlimit
マニュアルページの次の内容は次のとおりですRLIMIT_RSS
。
RLIMIT_RSSプロセスの常駐セット(RAMに常駐する仮想ページ数)の制限をページ単位で指定します。この制限は、次の場合にのみ有効です。Linux 2.4.x、x < 30で、次にのみ影響します。 クレイジーウェス(2)MADV_WILLNEEDを指定します。
madvice
syscallはカーネルの提案であり、カーネルでは無視できます。bash
マニュアルページにもulimit
次のように記録されています。
-m 最大常駐セットサイズ(多くのシステムがこの制限に準拠していません)
-m
うまくいかない理由は次のとおりです。
オプション情報-v
:
1024kbの仮想メモリを設定しました。
$ ulimit -v 1024
他のコンソールから:
$ strace -p <my_bash_pid>
. . .
getrlimit(RLIMIT_AS, {rlim_cur=RLIM64_INFINITY, rlim_max=RLIM64_INFINITY}) = 0
setrlimit(RLIMIT_AS, {rlim_cur=1024*1024, rlim_max=1024*1024}) = 0
. . .
setrlimit
マニュアルページの次の内容は次のとおりですRLIMIT_AS
。
RLIMIT_ASプロセスの仮想メモリ(アドレス空間)の最大サイズ(バイト単位)。この制限は通貨に影響します。ブルク(2)、マッピング(2)そして 再マッピング(2)、この制限を超えると、ENOMEM エラーが原因で失敗します。さらに、自動スタック拡張は失敗します(sigaltstack(2)を介して利用可能な代替スタックがない場合は、プロセスを終了するためにSIGSEGVが作成されます)。値が long なので、32 ビット long を使用するマシンでは、この制限が最大 2GiB か、このリソースが無制限です。
プログラムは、仮想プログラム記憶領域を構成する3つのセグメント(データ、コード、スタック)で構成されています。
コードセグメントは定数であり、プログラム命令を含む。
データセグメントは以下によって制御されます。
brk
システムコールのサイズ変更データセグメントプログラム(仮想メモリの一部)。mmap
システムコールは、ファイルまたはデバイスをプロセスの仮想メモリにマップします。多くのプログラムはCライブラリ()の標準関数を呼び出してメモリを(直接的または間接的に)割り当てます
malloc
。山(データセグメントの一部)。malloc
システムコールを呼び出してデータセグメントのサイズを変更しますbrk
。スタックは関数変数を保存します(変数はスタックからの割り当て中にメモリを占有します)。
したがって、この-v
オプションがあなたに適した理由です。
あなたの使命を果たすのに十分であれば、-v
他のことをする理由はありません。それだけで十分です。
プロセスの多くの特定のメモリ機能(メモリ圧力、スワップ使用量、RSS制限、OOMなど)を制御するには、次を使用することをお勧めします。cgroup メモリ能力。
あなたの申請書提供する私はあなたが使用することをお勧めしますシステムスライシング機能はcgroups
によって制御され制限されますsystemd
。