`ulimit` が期待どおりにメモリ使用量を制限しないのはなぜですか?

`ulimit` が期待どおりにメモリ使用量を制限しないのはなぜですか?

プロセスのメモリ使用量を制限しようとしています

$ulimit -m 2
$/usr/bin/time -l ./myProcess arg1 arg2

プロセスは終了せずにtime出力まで実行されます

        7.00 real         4.83 user         2.16 sys
4154855424  maximum resident set size
         0  average shared memory size
         0  average unshared data size
         0  average unshared stack size
   1014384  page reclaims
         0  page faults
         0  swaps
         0  block input operations
         2  block output operations
         0  messages sent
         0  messages received
         0  signals received
         0  voluntary context switches
        15  involuntary context switches

コマンドラインにもかかわらず、制限を超えていることを示していますulimit -m 5。オプションとも試しましたが-v、どちらも実際にメモリ使用量を制限しているようには見えません。また、サブプロセスのメモリ使用量を確認できないことがないよう-lに、 も試しましたtime。以下は、 all を使用した後のすべての制限です-m-v-l

$ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
file size               (blocks, -f) unlimited
max locked memory       (kbytes, -l) 3
max memory size         (kbytes, -m) 2
open files                      (-n) 256
pipe size            (512 bytes, -p) 1
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 709
virtual memory          (kbytes, -v) 2

CPU 時間を制限すると ( ulimit -t 3)、正常に動作し、3 秒後にプロセスが強制終了します。

質問

何か誤解している点があるのでしょうかulimit -m 5? 私の ulimit バージョンにバグがあるのでしょうか?

ulimitプロセス (必ずしも bash セッションではない) の時間とメモリ使用量を制限する代替手段はありますか?

バージョン

私はMAC OSX 10.11.6とにいますbash version 3.2.57

関連記事

「ulimit がメモリ使用量を制限しない」という投稿非常に関連していますが、受け入れられた回答では問題を解決する方法についての解決策は提供されていないと思います

答え1

最近の Linux カーネルでは、ulimitリリースごとに は意味を失っています。 は実際には使用できません。glibc-vのバージョンによっては でファイルをロードすることを好む可能性があるため、プロセスが開くすべてのファイルを含めるのに十分な大きさにmmap()設定する必要があります-v。その結果、フラグを-v使用して物理 RAM の使用を制限することはできません。

さらに、この-mフラグは何も行わないため、物理メモリの使用量を制限するために使用することもできません。

現在、物理 RAM の使用を制限するにはカーネルへのインターフェイスを使用する必要がありますcgroupsが、残念ながら API は少し使いにくいです。おそらく、いつの日か、パラメーターとして指定されたプロセスのメモリを制限できるnice、に似たプロセスが登場するでしょう。ionice

理論的には、最近のものならsystemd次のようなことができるはずです

systemd-run --scope --user -p MemoryMax=250M -- /path/to/program/to/use

すると、魔法のように動作するはずです。これが動作しない技術的な理由はありません (基盤となる Linuxcgroup機能は必要な機能をサポートしているため) が、一部のsystemdバージョンでは、単に暗黙的に失敗し、実際にはメモリ使用量を制限しません。プログラムを強制終了せずにメモリ消費量を減らすようにプログラムを押し進めたい場合は、オプション-p MemoryHigh=200Mになどを追加することもできます。ただし、超過すると、メモリ使用量を減らすためにカーネルがプロセスからすべてのメモリ (キャッシュを含む) を回収する余分な作業を行うため、プロセスがかなり遅くなることに注意してください。多くの場合、最大制限を強制する場合は、これは必要ありません。systemd-runMemoryHigh

関連情報