は、「64ビットオペレーティングシステム」のアドレス空間のサイズは必ずしも完全な64ビットの範囲をカバーしていないことに注意してください得ることができます。
例えば、実際に利用可能な仮想アドレス範囲は「唯一の」2x128TBです(つまり、64ビットx86、別名「AMD64」)。つまり、2つの分離した47ビットのチャンクで48ビットです。一部のSPARCシステムでは、2x2TBまたは2x8TB(41/44ビット)です。これは、MMUがこれらのプラットフォームで動作する方法によるものです。
これらのアーキテクチャ上の制限に加えて、オペレーティングシステムがアドレス空間をレイアウトする方法もここでは重要な役割を果たします。
64bit Windows on x64では、(64bitであっても)アプリケーションの仮想アドレスサイズを8TB(各カーネルとユーザ側で1)に制限しています。システム固有の制限内 - - setrlimit
を介して調整する(Linux、MacOSXのと*のBSDを含む)UN * Xシステムで
は、一方がgetrlimit()
介しを照会、及びできRLIMIT_AS
あります。 ulimit
コマンドで使用されます。プロセスが作成できるすべてのマッピング(mmap()
またはmalloc
バックエンド、sbrk()
経由)を含む、許可された仮想アドレス空間の上限を返す/設定します。 しかし、合計アドレス空間のサイズは、単一のマッピングの最大サイズと異なります。
これを考えると、64ビットLinuxでも仮想アドレス空間を使い果たすのは難しくありません。テストのために、mmap()
に同じ500GBファイル、たとえば200回試してみてください。最終的にmmapは失敗します。要するに
:あなたは仮想アドレス空間の外にいる一度
mmap()
は間違いなく失敗します。これは、仮想アドレスがであり、有効ビット数がであり、64ビットである可能性があるため、多くの「64ビット」アーキテクチャではやや驚くべきことに実現可能です。正確なカットオフはCPUとオペレーティングシステムによって異なり、上限はgetrlimit(RLIMIT_AS)
で問い合わせるか、setrlimit(RLIMIT_AS)
で設定します。
- アドレス空間の断片化は、異なる順序で異なるサイズのブロックで頻繁に
mmap()
/munmap()
を使用して64ビットで発生する可能性があります。これにより、最終的に単一のチャンクとしてマップできる最大サイズが制限されます。正確にこれが起こると予測するのは、あなたの "マッピング履歴"とオペレーティングシステムの仮想アドレス空間割り当てアルゴリズムの両方に依存するため、難しいです。 ASLR(アドレス空間レイアウトのランダム化)がOSによって実行されると、正確に予測できず、正確に再現できないことがあります。
malloc()
も、オーバーコミットによりシステム内の物理容量(物理+スワップ)よりも多くのメモリを「尋ねる」ことを可能にするシステム(Linuxのような)ではVA限界に達するまでに失敗します。何のオーバーコミットが有効にされていないマシン/オペレーティング・システムで
- マッピングのこれらのタイプは、実際のメモリまたはスワップによるバッキングストアを必要とするため、物理+スワップは、疲れているとき、
MAP_ANON
および/またはMAP_PRIVATE
との両方malloc()
とmmap()
は失敗します。
リトルテクニカルアップデート:上記のx86およびsparcと同様に、新しいARMv8(64ビットARM、Linuxでは「AArch64」と呼ばれます)MMUには、64の「分割」アドレス空間/アドレスのビット数は、40個だけが適切です。 Linuxはユーザーのために39ビット、仮想アドレスは0 ...
以降、カーネルは39ビット、仮想アドレスは... 0xFFFFFFFF.FFFFFFFF
です。したがって、512GB(これは、アプリケーションがmmap
を試している時点で既に使用されているものを除いています)です。
comments here(AArch64アーキテクチャイネーブラーカーネルパッチシリーズから)を参照してください。
ハードウェア障害。それはあなたに起こる可能性があります。 –