2

試行錯誤11_451_104の結果、これがマジック ナンバーであり、マシンが OOM エラーをスローする原因になることがわかりました。

を使用して11_451_103、保持できる限り多くのデータを詰め込んでいます。

private static void init() {
    int i = 0;
    try {
        while (++i < 11451104) {
            list.add("a");
        }
    } catch (OutOfMemoryError e) {
        System.out.println("oh no, not again :("); // <-- Not getting here
    }
}

次の行にある場合

    String x = "some new string";

ヒープはもう 1 つの文字列にスペースを割り当てることができないため、例外が発生することが予想されます。それでも、そうではありません。

この新しい文字列をリストに追加しようとすると、

    String x = "some new string"; // <-- expect OOM Error to happen here
    list.add(x);

プログラムは OOM で中止されます。文字列の割り当て時にこれが発生しなかったのはなぜですか?

未知の (おそらく非常に大きな) 量のデータを保持する必要がある可能性があるため、OOM が可能であることを知って自分自身を保護する最善の方法は? ディスクへのシリアル化と永続性は、これを処理する方法ですか?

4

2 に答える 2

6

文字列の割り当て時にこれが発生しなかったのはなぜですか?

このlist.add(...)メソッドは、メモリを割り当てている場合もあります。リストが の場合、呼び出しLinkedListごとaddに新しいリスト ノードが作成されます。の場合ArrayListaddバッキング配列が再割り当てされる可能性があります。

(更新"a"- 新しい文字列オブジェクトを作成していないことに気付きました。リストに同じリテラル文字列を継続的に追加しているため、文字列の割り当てでOOMEが発生しないことが保証されます!)

OOMの可能性があることを知って自分を守る最善の方法...

OOME をキャッチして回復しようとするのは魅力的ですが、リスクが伴う可能性があります。問題は、アプリケーション (アプリケーション コードによって呼び出されるライブラリ メソッドなど) が実際に何を割り当てようとしていたのか、また、その割り当てがError都合の悪いときに発生し、重要なデータ構造が部分的または矛盾した状態。したがって、アプリケーションが回復を試みるのに適した状態にない可能性があります。

一般に、OOME が発生したときに行う最も安全な方法は、アプリケーションをすぐに終了させることです。トランザクションなどをコミットしようとしないでください。アプリケーションのデータベース接続ソケット/パイプ/その他が OS によって閉じられたときに、データベースの自動ロールバックがコミットされていないトランザクションをクリーンアップします。

実際、「回復を試みるな」というアドバイスはすべてのError例外に適用されます。ただ、OOME は、開発者がアドバイスを無視する傾向があるケースであるというだけです。


「自分自身を保護する」という点では、一般的な解決策は、重要な状態のコピーを不揮発性ストレージに安全に保管することです。たとえば、データベースへの書き込み、フラット ファイルへのシリアライズなどです。詳細 (どのテクノロジが最適かなど) は、データ、アプリケーションでの使用方法、およびアプリケーションを再起動可能にする方法によって異なります。

問題/状況は、起こりうるアプリケーションのクラッシュ、OS の再起動、電源障害などに対処する問題と質的に違いはありません。

于 2012-07-06T02:46:49.697 に答える
1

私はそれを処理しようとしないでください。とにかく確実にできることは何ですか?

これはエラーであり、例外ではありません。乱暴に手を振り始め、必要に応じてウォッチドッグでプロセスを再開します。

使用可能なメモリ量を超えている疑いがある場合:

  1. ストリーミングへのアプローチを変更する、および/またはよりスリムにする。[一時的な] メモリの使用量を減らす
  2. より多くの仮想メモリが必要 (OSおよびJVM)
  3. データベース、ディスクベースのハッシュなど、ストレージに基づく構造を使用します (これは「ディスクへのシリアライゼーションと永続化」の形式です)。
于 2012-07-06T02:46:18.373 に答える