メモリ不足状態を処理しますか?


9

malloc0を返すか、新しい例外がスローされた場合はどうしますか?停止するか、OOM状態を生き残るか、ユーザーの作業を保存しようとしますか?


4
StackOverflowの上で関連stackoverflow.com/questions/763159/...
ysolik

11
ああ。私はこれを「マナから」と読み続けます。過去のビデオゲームが多すぎると思います。:)
アダムリア

回答:


4

クラッシュを回避するようなOOMは回避します。

一度に大量の作業を行う(および大量のメモリを割り当てる)ことは避けてください。ディスク上にデータを保持し、OSのディスクキャッシュを信頼し、メモリマップされたIOを可能な限り使用し、一度にデータのごく一部のみを操作します。大量のデータをオンラインにする必要がある場合(低レイテンシで提供される)、すべての大規模な検索エンジン企業が行うように、複数のマシンのメモリにそれらを保持します。またはSSDを購入します。


どうやらこれは最も理にかなっています。
mbq

2
私は、複数の動的モジュールとマルチスレッドシステムでは(サードパーティからいくつかの)実現した後も、そこに優雅にOOM(RAII、例外安全性、何とか...)をどのように扱うかについての素晴らしい議論があったが、あなたのスレッドはありませんでしたクラッシュ、すべてのスレッドがOOMを見る不幸な瞬間があります。一人でも先に進むことにした場合は、目撃証言しかできません。
2010年

13

この質問に答えるほとんどの人はおそらくmallocが0を返すことは非常に現実的な可能性がある組み込みシステムで働いたことはないでしょう。私が現在取り組んでいるシステムでは、合計で4.25KバイトのRAM(つまり、4352バイト)があります。スタックに64バイトを割り当てていますが、現在1600バイトのヒープがあります。ちょうど昨日、メモリの割り当てと解放を追跡できるように、ヒープウォークルーチンをデバッグしていました。ヒープウォークは、静的に割り当てられた小さな(30バイト)バッファーを使用して、シリアルポートに出力します。リリース版では無効になります。

これは消費者向け製品であるため、製品がリリースされたらメモリ不足にならないようにしてください。開発中だと思います。いずれにせよ、私にできることは、スピーカーを数回鳴らして強制的に再起動することです。


2
小さなスペースの中にフィットする機能は素晴らしいです...それは盆栽のような芸術の形です
rwong

6
組み込みシステムのプロジェクトの多くは、メモリの動的割り当てを禁止しています。OOMの唯一のケースはスタックオーバーフローのままです。
mouviciel

あなたは正しいですが、特に最初の文はそうです。これのほとんどは、幸運にもほとんどの開発者にとって重要ではありません。
Konrad Rudolph

4

正直に言うと、これまでに行ったすべてのプロジェクト(まだどこでも作業していないことを念頭に置いてください)では、それが発生する可能性があるとは考えていません。

さらに、OOMを処理するには、リソースを事前に割り当てて、エラーメッセージを表示したり、すべてを保存したりする必要があります。

最近では、ピーナッツよりもメモリのコストが低く、頻繁に発生するはずのないものだと感じています。保護されたメモリの黎明期とそれ以前では、おそらくそれが問題でしたが、今は?私が今まで見た唯一のOOMエラーは、バグのあるコードによるものでした。


プロセスがすでに持っているメモリの一部を再利用することを考えて、生き残って回復するか(有用なものをダンプした場合はハードメモリ)、またはデータ+残りとして保存しようとします。
mbq

2

とにかく、mallocの戻りコードをチェックしても、通常は無意味です。

最新のオペレーティングシステムはメモリをオーバーコミットします。実際に利用可能なメモリよりも多くのメモリをプロセスに提供します。プロセスに付与されるメモリは仮想であり、すべて1つのゼロ化されたページにマップされます。

メモリに書き込むまでは、物理的で一意のページがプロセスに割り当てられます。この割り当てが失敗した場合、カーネルはメモリを見つけようとしてプロセス(おそらくあなたのもの)を終了します。その時点では、これ以上できることはありません。


私は内部で長いスリープ状態のwhileループに入り、プロセスがOOMキラーに耐えられるかどうかを回復することを考えていました。0アドレスを使用しようとしたためにプロセスがかなり終了したという印象を受けましたが、確かなテストは行っていません。
mbq

OOMキラーに対処するために特別なことをする必要はありません。プロセスがそれをトリガーしたが、選択されなかった場合、それは決してわかりません。すべてが十分なメモリがあるかのように動作します。一方、あなたのプロセスが選択された場合、それは終了し、それに対してあなたができることも何もありません。
Kristof Provost

しかし、OOMがメモリを解放するのを待ってから、再度割り当てて続行することもできます。malloc / newはこれが起こるのを待っていないようです。
mbq

いいえ、できません。割り当ては常に成功します。必要なすべての仮想メモリを取得します。物理メモリが割り当てられるのは、触れるまではありません。割り当てられていないページをタッチするとすぐに、プロセスが中断されます。カーネルはより多くのメモリを探すため、より多くのメモリのプロセスを強制終了する可能性があります。それが成功した場合(そしてあなたを殺すことはありません!)、ページが割り当てられ、プロセスが再開します。プロセスがこれが発生したことを通知する方法はありません。
Kristof Provost

2
Windowsがオーバーコミットしないことは確かです。コミットできるのはRAM以上ですが、RAM + swapfile以下です。
CodesInChaos

2

組み込みシステム、リアルタイムシステム、または障害が命を落とすほどの重大なシステム、または数十億ドルに及ぶシステムを対象に開発を行っている場合を除き、メモリ不足の状態を心配することは、おそらく経済的に価値がありません。

ほとんどの場合、新しいオブジェクトを作成したり、何かを実行するタスクを実行したりするためのメモリがないため、とにかくメモリ不足のときにできることはほとんどありません。OOMを処理するアプリのコストと、それによって得られるメリットを比較検討する必要があります。


リアルタイムシステムは、他のシステムよりもmallocの失敗について詳細にチェックする必要はありません。
zneak

@zneak-真実ではない。リアルタイムシステムは予測可能である必要があり、特に計画を立てていない限り、メモリ不足は予測できません。
エリックファンケンブッシュ

では、OOMに到達したら、これから何をしますか?
zneak

メモリの解放、プロセスのキャンセルなど。リアルタイムシステムは確定的でなければならないため、通常、仮想メモリやスワップシステムはありません。そのため、メモリ不足になりやすくなります。
Erik Funkenbusch

OOMエラーに必然的につながる特定のコードパスを考えると、クラッシュがメモリの解放とプロセスのキャンセルよりも決定論的アプローチではないことはわかりません。
zneak

1

私はいつもエラーをチェックします。何かがエラー状態を返した場合は、プログラムで処理する必要があります。「メモリ不足です、行かなきゃ!」というメッセージであっても、「アクセス違反」「コアダンプ」などなんでもない。1つは処理するエラー状態で、もう1つはバグです。そして、ユーザーも同様にそれを認識します。

特定のケースでは、オペレーションをロールバックして、失敗したポイントに到達するまで割り当てたリソースを解放し、エラーを報告して、実行を継続することができます(アプリケーションを終了しようとしているときに、すぐに終了するオプション)。このようにして、ユーザーは何をするかを決定したり、ファイルをいじったり、ファイルを閉じたりするなどして、メモリを解放することができます。もちろん、状況にどう対処できるかは、プログラムに大きく依存しますインタラクティブである必要があるのは、おそらくエラーをログに記録して終了するか続行するだけです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.