x64 Linuxの単一プロセスにはメモリ制限がありますか?単一プロセスx64 Linuxで最大可能メモリ
私たちは32GbのRAMを搭載したLinuxサーバーを実行しています。私は大量のRAMを必要とするコーディングの1つのプロセスにそのほとんどを割り当てることができますか?
x64 Linuxの単一プロセスにはメモリ制限がありますか?単一プロセスx64 Linuxで最大可能メモリ
私たちは32GbのRAMを搭載したLinuxサーバーを実行しています。私は大量のRAMを必要とするコーディングの1つのプロセスにそのほとんどを割り当てることができますか?
特定のカーネルには制限がありますが、現代の64ビットLinuxでは、単一プロセスの制限は32GBをはるかに超えています(プロセスが64ビットの実行可能ファイルであると仮定します)。様々なディストリビューションでもプロセスごとの制限がsysctl
に設定されている可能性がありますので、ローカル環境をチェックして、任意の上限が設定されていないことを確認してください(RPMベースのシステムではipcs -l
もチェックしてください)。
AMD64ポート用のDebian port documentationは、プロセスごとの仮想アドレス空間の制限が128TiB(物理メモリの2倍)であることを特に言及しています。
リソース制限は、setrlimitシステムコールを使用して設定されます。シェルの組み込み関数で変更できます(例:ulimit
bash、limit
、zsh)。
実際の制限は、RAMのサイズとスワップサイズにも関係します。 free
コマンドはこれらを表示します。 (システムによってはメモリオーバーコミットがありますが、それは危険です)。
実際にはRAMを使用しないプロセスでは、(malloc
によって呼び出される可能性があります)などのシステムコールを使用して、virtual memoryを消費します。その呼び出しでファイルの一部をメモリにマップすることさえできます。
プロセス1234のメモリマップについては、/proc/1234/maps
ファイルを参照してください。自分のアプリケーションから、/proc/self/maps
を読んでください。また、/proc/1234/smaps
と/proc/self/smaps
もあります。そのcat
を実行しているプロセスのメモリマップを理解するには、コマンドcat /proc/self/maps
を実行してください。
32Gb RAMマシンでは、通常、31Gbのプロセススペースでプロセスを実行できます(他の大きなプロセスは存在しないものとします)。 64Gbのスワップでも64Gb以上のプロセスを実行できますが、それは信じられないほど遅くなります(ほとんどの時間はディスクへのスワップに費やされます)。スワップスペースを追加することができます(たとえば、ファイルにスワップし、dd
で初期化してからmkswap
とし、swapon
でアクティブにする)ことができます。
サーバーをコーディングする場合は、memory leaksに十分注意してください。 valgrind
ツールは、このようなバグを見つけ出すのに役立ちます。また、使用することもできますBoehm's garbage collector
現在の64ビットLinuxカーネルには、64TBの物理RAMと128TBの仮想メモリに制限があります(RHEL limitsおよびDebian port参照)。 CPUのアドレスレジスタがすべてのビットをどのように使用するか(上位ビットはReadOnly、Writableなどのページフラグに使用されるため)、現在のx86_64 CPU(つまり、PCに搭載されているCPU)は2^48 = 256TB ExecuteDisable、PagedToDiscなど)、しかし、この仕様では、2^64 = 16EB(Exa Bytes)で最大に達する真の64ビットアドレスモードに切り替えることができます。しかし、マザーボードとCPUダイは、アドレスバスを介してメモリアドレスの48ビットすべてをRAMチップに供給するために非常に多くのピンを持たないため、物理RAMの制限は低くなりますが(製造元によって異なります)、仮想アドレススペースは本質的には上記の仮想メモリの上限までマザーボードに搭載できるRAMの容量を超える可能性があります。
スタック、mmap()領域(およびダイナミックライブラリ)、プログラムコード自体にさまざまなサイズがある可能性があるため、プロセスのメモリ仮想アドレス空間がどのように設定されているかによってプロセスあたりの制限が高くなります。プロセス空間にマップされます。これらの設定の一部は、リンカに引数を渡すことで変更することも、ソースコード中の特別な指令によって変更することも、プログラムでバイナリファイルを直接変更することもできます(バイナリにはELF形式があります)。また、マシン(ルート)の管理者が設定した、またはユーザーが持っている制限があります(コマンド "ulimit -a"の出力を参照)。これらの制限は、ソフトまたはハードとすることができ、ユーザーはハード制限を克服できません。
また、メモリオーバーコミットの割り当てを許可するようにLinuxカーネルを設定することもできます。この場合、プログラムは膨大な量のRAMを割り当ててから、ほんの数ページしか使用できません(スパース配列、スパース行列を参照)。Linux kernel documentationを参照してください。この場合、プログラムは要求されたメモリをデータで満たすだけで失敗しますが、メモリ割り当ての時点では失敗します。
あなたはそれを試して自分で見ることができます。実用的な制限はありません。私はUbuntuの64GBマシンに60GB以上の連続したメモリを割り当てることができました。 – Mysticial