
メモリ不足(OOM )は、コンピュータの動作において望ましくない状態であり、プログラムやオペレーティングシステムが使用できるメモリが追加で割り当てられなくなる状態です。このようなシステムでは、追加のプログラムをロードすることができず、多くのプログラムは実行中にメモリに追加データをロードするため、正しく動作しなくなります。これは通常、ディスクのスワップ領域を含む利用可能なメモリがすべて割り当てられているために発生します。
歴史的に見ると、メモリ不足の状態は現在よりも頻繁に発生していました。これは、初期のプロセッサが大量のメモリをアドレス指定できなかったことやコスト上の制約から、初期のコンピュータやオペレーティングシステムは、物理的なランダムアクセスメモリ(RAM)の容量が限られていたためです。仮想メモリの登場によりスワップ領域の使用が可能になったため、この状態は以前ほど頻繁には発生しなくなりました。現代のプログラムのほとんどは、実行時にメモリを自由に割り当てたり解放したりできることを前提としており、その前提が満たされない場合は制御不能な形で失敗する(クラッシュする)傾向があります。一方、古いプログラムは、メモリを一度だけ割り当て、すべての作業を実行するのに十分なメモリが確保できたかどうかを確認し、それ以上メモリが確保されないことを前提としていました。そのため、メモリ不足エラー(OOME)メッセージが表示されてすぐに失敗するか、期待どおりに動作するかのどちらかでした。
MS-DOSなどの初期のオペレーティングシステムは、マルチタスクをサポートしていませんでした。プログラムには物理メモリが割り当てられ、必要に応じて使用できました。物理メモリはしばしば貴重なリソースであり、常駐型アプリケーションなどによってメモリが枯渇すると、実行中のアプリケーションが終了するまで、それ以上のアプリケーションを起動することはできませんでした。
最新のオペレーティングシステムは仮想メモリを提供しており、プロセスにはメモリ範囲が割り当てられますが、そのメモリは実際の物理RAMに直接対応するものではありません。仮想メモリは、物理RAM、mmap(Unix系OSの場合)またはMapViewOfFile(Windowsの場合)を介したディスクファイル、あるいはスワップ領域によってバックアップされ、オペレーティングシステムは必要に応じて仮想メモリページを移動できます。仮想メモリは物理メモリによるバックアップを必要としないため、枯渇することはまれであり、通常はオペレーティングシステムによってリソース消費に他の制限が課されます。(例えば、Windowsはコミット課金方式を使用して仮想メモリのサイズを制限しています。)
ムーアの法則が予測した通り、すべてのコンピュータの物理メモリ容量はほぼ指数関数的に増加していますが、プログラムやファイル自体のサイズが大きくなることで、ある程度相殺されています。仮想メモリをサポートするコンピュータで、ロードされたデータの大部分がハードディスク上に存在する場合、物理メモリは不足するものの仮想メモリは不足しないため、ページングが過剰に発生することがあります。この状態はスラッシングと呼ばれ、通常、一部のプログラムを閉じるかコンピュータを再起動するまで、コンピュータが使用不能になります。こうした理由から、現代のコンピュータでは、アプリケーションがメモリ不足のメッセージに遭遇することはめったにありません。
しかし、最新のコンピュータでもOOM状態が発生する可能性は依然としてあります。最新のコンピュータで典型的なOOMが発生するのは、オペレーティングシステムが仮想メモリをこれ以上作成できない場合です。これは、すべての潜在的なバックアップデバイスがいっぱいになったか、エンドユーザーがそれらを無効にしたためです。この状態は、コピーオンライト後に発生する可能性がありますfork()。
Linuxなどのオペレーティングシステムのカーネルは、1 つ以上のプロセスを終了させることで、この種の OOM 状態から回復しようとします。このメカニズムはOOM キラーとして知られています。[ 1 ] [ 2 ] Linux 4.6 (2016 年 5 月にリリース) では、OOM 状況に変更が加えられ、検出と信頼性が向上しました。[ 3 ] [ 4 ] OOM キラーにおけるcgroup認識は、2018 年 10 月にリリースされたLinux カーネル 4.19で実装され、cgroup を単一の単位として終了させる機能が追加されました。[ 5 ]
一部のLinuxシステムではOOM Killerの起動が遅れるため、 [ 6 ]メモリが手遅れになる前にOOM状態から回復するのに役立つデーモンやカーネルパッチがいくつか存在する。
システム全体の物理メモリ制限とは別に、システムによっては各プロセスが使用できるメモリ量に制限を設けている場合があります。通常はポリシーの問題ですが、このような制限は、OSのアドレス空間がプロセスレベルで使用可能なアドレス空間よりも大きい場合にも発生する可能性があります。一部のハイエンド32ビットシステム(物理アドレス拡張が有効になっているものなど)は、8ギガバイト 以上のシステムメモリを搭載していますが、 32ビットのフラットメモリモデルでは、単一のプロセスがアクセスできるのはそのうち4GBまでです。
プロセスがプロセスごとの制限を超えてさらにメモリを割り当てようとすると、エラー状態になります。たとえば、メモリを割り当てるためのC 標準関数は、割り当てに失敗するとNULLmalloc()を返します。適切に動作するアプリケーションは、この状況を処理する必要があります。標準 C++ は、物理 RAM が枯渇したときではなく、仮想メモリの割り当てに失敗したときに例外をスローします。Javaでは、Java 仮想マシン(JVM) のメモリが不足すると例外がスローされ、C#では例外がスローされます。POCO C++ ライブラリには、メモリが不足した場合に例外をスローするクラスがあります。operator newbad_allocOutOfMemoryErrorOutOfMemoryExceptionOutOfMemoryExceptionMemoryPool