java.lang.OutOfMemoryError?


101

のドキュメントjava.lang.Error言う:

ErrorはThrowableのサブクラスであり、妥当なアプリケーションがキャッチしようとしてはならない重大な問題を示します

しかしjava.lang.Error、のサブクラスとjava.lang.Throwable同様に、このタイプのThrowableをキャッチできます。

なぜこの種の例外をキャッチするのが良くないのか理解しています。私が理解している限り、キャッチすることにした場合、キャッチハンドラはそれ自体でメモリを割り当てるべきではありません。それ以外の場合OutOfMemoryErrorは再びスローされます。

だから、私の質問は:

  1. 捕まえるのjava.lang.OutOfMemoryErrorが良いかもしれない現実のシナリオはありますか?
  2. キャッチすることにした場合java.lang.OutOfMemoryError、キャッチハンドラがそれ自体でメモリを割り当てないようにするにはどうすればよいですか(ツールやベストプラクティス)。


最初の質問については、ユーザーに問題を通知するために(少なくとも試みて)OutOfMemoryErrorをキャッチすることを付け加えておきます。以前は、catch(Exception e)句によってエラーがキャッチされず、ユーザーにフィードバックが表示されませんでした。
JosepRodríguezLópez2013

1
巨大な配列を割り当てるなど、特定の場合があります。その場合、その操作に関するOOMエラーをキャッチし、適切に回復できます。しかし、try / catchをコードの大きな塊に配置し、完全に回復して続行しようとすることは、おそらく悪い考えです。
Hot Licks 14

回答:


85

ここでのほとんどの回答に同意し、同意しません。

OutOfMemoryError(WindowsおよびSolaris JVMでの)私の経験では、キャッチしたいシナリオがいくつかありますが、ごくまれOutOfMemoryErrorに、JVMが死に至ることはありません。

をキャッチする理由は1つだけOutOfMemoryErrorです。それは、リソースを適切に解放し、リソースをクリーンに解放し、可能な限り失敗の理由をログに記録することです(それが可能な場合)。

一般に、これOutOfMemoryErrorは、ヒープの残りのリソースでは満足できないブロックメモリ割り当てが原因で発生します。

ときにError、ヒープが失敗割り当て前と割り当てられたオブジェクトの同じ量が含まれており、今、実行時のクリーンアップのために必要とされるにも多くのメモリを解放するためにオブジェクトへの参照をドロップする時間ですスローされます。これらの場合、続行することも可能かもしれませんが、JVMが修復可能な状態であることを100%確実にすることはできないため、これは間違いに悪い考えです。

OutOfMemoryErrorJVMがcatchブロックでメモリ不足であることを意味しないデモ:

private static final int MEGABYTE = (1024*1024);
public static void runOutOfMemory() {
    MemoryMXBean memoryBean = ManagementFactory.getMemoryMXBean();
    for (int i=1; i <= 100; i++) {
        try {
            byte[] bytes = new byte[MEGABYTE*500];
        } catch (Exception e) {
            e.printStackTrace();
        } catch (OutOfMemoryError e) {
            MemoryUsage heapUsage = memoryBean.getHeapMemoryUsage();
            long maxMemory = heapUsage.getMax() / MEGABYTE;
            long usedMemory = heapUsage.getUsed() / MEGABYTE;
            System.out.println(i+ " : Memory Use :" + usedMemory + "M/" + maxMemory + "M");
        }
    }
}

このコードの出力:

1 : Memory Use :0M/247M
..
..
..
98 : Memory Use :0M/247M
99 : Memory Use :0M/247M
100 : Memory Use :0M/247M

重要な何かを実行している場合、私は通常をキャッチしError、それをsyserrに記録してから、選択したロギングフレームワークを使用してログに記録してから、リソースを解放し、クリーンな方法で終了します。起こり得る最悪は何ですか?JVMはとにかく死んでいる(またはすでに死んでいる)ので、それをキャッチするErrorことにより、少なくともクリーンアップの可能性があります。

注意点は、クリーンアップが可能な場所でのみ、これらのタイプのエラーのキャッチをターゲットにする必要があることです。catch(Throwable t) {}いたるところに毛布をかけたり、そのような無意味なことをしたりしないでください。


同意します。新しい回答について実験を投稿します。
ミスタースミス

4
「JVMが修復可能な状態にあることを100%確信することはできません」:いつでもOutOfMemoryErrorスローされる可能性があるため、プログラムが不整合な状態になったポイントからスローされた可能性があるためです。stackoverflow.com/questions/8728866/…を参照してください
Raedwald、2012年

OpenJdk1.7.0_40では、このコードを実行してもエラーや例外は発生しません。メガバイトをギガバイト(1024 * 1024 * 1024)に変更しました。残りのコードでは使用されていないため、オプティマイザが変数「byte [] bytes」を削除するためですか?
RoboAlex 2013

「OutOfMemoryErrorをキャッチするシナリオは多数あります」「OutOfMemoryErrorをキャッチする理由は1つしかない」です。あなたの心を作ります!!!
スティーブンC

3
OutOfMemoryエラーをキャッチしたい場合の実際のシナリオ:2Gを超える要素を含む配列を割り当てようとしたことが原因で発生した場合。この場合、エラー名は少し誤称ですが、それでもOOMです。
Charles Roth、

31

あなたそれから回復することができます:

package com.stackoverflow.q2679330;

public class Test {

    public static void main(String... args) {
        int size = Integer.MAX_VALUE;
        int factor = 10;

        while (true) {
            try {
                System.out.println("Trying to allocate " + size + " bytes");
                byte[] bytes = new byte[size];
                System.out.println("Succeed!");
                break;
            } catch (OutOfMemoryError e) {
                System.out.println("OOME .. Trying again with 10x less");
                size /= factor;
            }
        }
    }

}

しかし、それは意味がありますか?他に何をしたいですか?なぜ最初にそれほど多くのメモリを割り当てるのですか?メモリが少なくても大丈夫ですか?とにかく、それをすでに利用してみませんか?それが不可能な場合は、JVMに最初からより多くのメモリを割り当てるだけではどうでしょうか?

あなたの質問に戻る:

1:java.lang.OutOfMemoryErrorをキャッチすることをお勧めする実際のシナリオはありますか?

何も思い浮かびません。

2:java.lang.OutOfMemoryErrorをキャッチする場合、catchハンドラーがそれ自体でメモリを割り当てないことをどのように確認できますか(ツールまたはベストプラクティス)?

OOMEの原因によって異なります。tryそれがブロックの外側で宣言され、それが段階的に起こった場合、あなたの可能性はほとんどありません。事前にいくつかのメモリ領域を予約することをお勧めします。

private static byte[] reserve = new byte[1024 * 1024]; // Reserves 1MB.

そして、OOME中にゼロに設定します。

} catch (OutOfMemoryException e) {
     reserve = new byte[0];
     // Ha! 1MB free!
}

もちろん、これはまったく意味がありません;)アプリケーションに必要なだけの十分なメモリをJVMに与えるだけです。必要に応じてプロファイラーを実行します。


1
スペースを予約しても、実際のソリューションは保証されません。そのスペースは他のスレッドでも使用される可能性があります;)
Wolph 2010

@Wolph:次に、JVMにメモリを追加します!O_o All with all it it
is

2
エラーをトリガーしたオブジェクトは単一のBIGオブジェクト(配列)であるため、最初のスニペットが機能します。catch句に到達すると、メモリを大量に消費するJVMによって収集されます。tryブロックの外、または他のスレッド、または同じcatchで同じオブジェクトを使用していた場合、JVMはそれを収集しないため、あらゆる種類の新しい単一オブジェクトを作成できません。たとえば、2番目のスニペットは機能しない可能性があります。
ミスタースミス

3
単純にそれを設定しないのはなぜnullですか?
Pacerier 2011

1
@MisterSmithコメントは意味がありません。ラージオブジェクトは存在しません。もともと割り当てられていませんでした。OOMをトリガーしたため、GCは必要ありません。
ローン侯爵

15

一般に、OOMをキャッチして回復しようとするのは悪い考えです。

  1. OOMEは、アプリケーションが知らないスレッドを含む他のスレッドにもスローされる可能性があります。そのようなスレッドはすべて停止し、通知を待機していたものはいつまでもスタックする可能性があります。つまり、アプリが最終的に破損する可能性があります。

  2. 正常に回復した場合でも、JVMはヒープの枯渇に悩まされている可能性があり、その結果、アプリケーションのパフォーマンスはわずかです。

OOMEで行う最善の方法は、JVMを停止させることです。

(これは、JVM 死ぬことを前提としてます。たとえば、TomcatサーブレットスレッドのOOM はJVMを強制終了しないため、Tomcatが要求に応答しない緊張状態になります...再起動。)

編集

OOMを捕まえるのは悪い考えだと言っているのではありません。その後、故意にまたは見落としによってOOMEからの回復を試みると、問題が発生します。OOMを(直接、またはErrorまたはThrowableのサブタイプとして)キャッチした場合は、それを再スローするか、アプリケーション/ JVMが終了するように調整する必要があります。

余談:これは、OOMが直面する最大の堅牢性のために、アプリケーションはThread.setDefaultUncaughtExceptionHandler()を使用して、OOMEがスローされたスレッドに関係なく、OOMEのイベントでアプリケーションを終了させるハンドラーを設定する必要があることを示唆しています。これについての意見に興味があります...

他の唯一のシナリオは、OOMが付随的な損害を引き起こしていないことが確実にわかっている場合です。つまり、あなたは知っています:

  • OOMEを具体的に引き起こしたもの、
  • アプリケーションがそのときに実行していたこと、およびその計算を単に破棄してもよいこと
  • (ほぼ)同時OOMEが別のスレッドで発生することはあり得ないこと。

これらのことを知ることができるアプリケーションがありますが、ほとんどのアプリケーションでは、OOME後の継続が安全であるかどうかを確実に知ることはできません。試してみると、経験的に「動作する」としても。

(問題は、「予期された」OOMEの結果が安全であること、および「予期されなかった」OOMEがtry / catch OOMEの制御内で発生しないことを示すには正式な証明が必要であることです。)


はい、あなたに賛成です。一般的に、それは悪い考えです。しかし、なぜ私はそれを捕まえる可能性があるのですか?:)
Denis Bazhenov 2010

@dotsid-1)キャッチする必要がある場合があるため、および2)OOMをキャッチできないようにすると、言語やJavaランタイムの他の部分に悪影響が及ぶため。
スティーブンC

1
あなたは言う:「あなたがそれを捕らえなければならない場合があるから」。これは私の元の質問の一部でした。OOMEをキャッチしたいのはどのような場合ですか?
Denis Bazhenov、2010

1
@dotsid-編集した回答を参照してください。OOMをキャッチするために私が考えることができる唯一のケースは、OOMのイベントでマルチスレッドアプリケーションを強制的に終了するためにこれを行う必要がある場合です。のすべてのサブタイプに対してこれを実行したい場合がありErrorます。
スティーブンC

1
OOMEを捕まえるだけの問題ではありません。それらから回復する必要もあります。(たとえば)別のスレッドに通知することになっている場合、スレッドはどのように回復しますか...しかし、OOMEを取得しましたか?もちろん、JVMが死ぬことはありません。しかし、OOMEをキャッチしたために再起動されたスレッドからの通知を待機するスレッドがスタックしているため、アプリケーションが動作を停止する可能性があります。
スティーブンC

14

はい、現実のシナリオがあります。これが私のものです。ノードあたりのメモリが限られているクラスターで、非常に多くのアイテムのデータセットを処理する必要があります。与えられたJVMインスタンスは多くの項目を次々に通過しますが、いくつかの項目は大きすぎてクラスターで処理できOutOfMemoryErrorません。後で、RAMの多いコンピューターで大きなアイテムだけを再実行できます。

(失敗するのは配列の単一のマルチギガバイト割り当てであるため、JVMはエラーをキャッチした後も問題なく、他のアイテムを処理するのに十分なメモリがあります。)


だからあなたはbyte[] bytes = new byte[length]size以前の時点で確認しないでください。
Raedwald、2012年

1
sizeより多くのメモリで同じことがうまくいくからです。ほとんどの場合は問題ないので、例外を経由します。
Michael Kuhn 2012年

10

OOMEをキャッチすることが理にかなっているシナリオは確かにあります。IDEAはそれらをキャッチし、起動メモリの設定を変更するためのダイアログをポップアップ表示します(その後、終了すると終了します)。アプリケーションサーバーがそれらをキャッチして報告する場合があります。これを実行するための鍵は、ディスパッチ時に高レベルで実行することです。これにより、例外をキャッチしているポイントで大量のリソースが解放される合理的な可能性があります。

上記のIDEAシナリオに加えて、一般的にキャッチはOOMだけでなく、スロー可能である必要があり、少なくともスレッドが間もなく終了するコンテキストで実行する必要があります。

もちろん、ほとんどの場合、メモリが不足していて、状況は回復できませんが、それが理にかなっている方法があります。


8

私の場合、OutOfMemoryErrorをキャッチするのが良いアイデアかどうか疑問に思っていたので、この質問に出くわしました。このエラーのキャッチが誰か(つまり、私)にとって意味のある別の例を示すために部分的にここに回答し、実際に私の場合にそれが良いアイデアであるかどうかを部分的に調べるために(私は非常に若い開発者なので、私は決してできません)私が書いたコードの1行についても確認してください)。

とにかく、私は異なるメモリサイズの異なるデバイスで実行できるAndroidアプリケーションに取り組んでいます。危険な部分は、ファイルからビットマップをデコードして、それをImageViewインスタンスに配置することです。デコードされたビットマップのサイズの点で、より強力なデバイスを制限したくありません。また、非常に低いメモリで遭遇したことのない古いデバイスでアプリが実行されないことも確認できません。したがって、私はこれを行います:

BitmapFactory.Options bitmapOptions = new BitmapFactory.Options(); 
bitmapOptions.inSampleSize = 1;
boolean imageSet = false;
while (!imageSet) {
  try {
    image = BitmapFactory.decodeFile(filePath, bitmapOptions);
    imageView.setImageBitmap(image); 
    imageSet = true;
  }
  catch (OutOfMemoryError e) {
    bitmapOptions.inSampleSize *= 2;
  }
}

このようにして、私は彼らの、またはむしろ彼らのユーザーのニーズと期待に応じて、多少なりとも強力なデバイスを提供することができます。


1
別のオプションは、試行して失敗するのではなく、処理できるビットマップの大きさを計算することです。「例外は例外的なケースに使用されるべきです」-私は誰かが言ったと思います。しかし、私が言うには、あなたの解決策は最も簡単な方法のようであり、おそらく最良ではないかもしれませんが、おそらく最も簡単です。
jontejj 2013

コーデックによって異なります。10MBのbmpはおそらく10MBをわずかに超えるヒープしか生じないが、10MBのJPEGは「爆発」すると想像してください。コンテンツの複雑さに応じて大幅に変化する可能性があるXMLを解析したい場合も同じです
Daniel Alder

5

はい、本当の質問は「例外ハンドラーで何をするつもりですか?」ほとんどすべての場合、より多くのメモリを割り当てます。OutOfMemoryErrorが発生したときに診断作業を行う場合は、-XX:OnOutOfMemoryError=<cmd>HotSpot VMが提供するフックを使用できます。OutOfMemoryErrorが発生したときにコマンドを実行し、Javaのヒープ外で何か便利なことができます。そもそもアプリケーションがメモリ不足にならないようにしたいので、なぜそれが起こるのかを理解することが最初のステップです。次に、必要に応じてMaxPermSizeのヒープサイズを増やすことができます。その他の便利なHotSpotフックを以下に示します。

-XX:+PrintCommandLineFlags
-XX:+PrintConcurrentLocks
-XX:+PrintClassHistogram

完全なリストはこちら


それはあなたの考えよりもさらに悪いです。(ステートメントからだけでなく)OutOfMemeoryError プログラムの任意の時点でがスローされる可能性があるため、new例外をキャッチすると、プログラムは未定義の状態になります。
Raedwald、2015年

5

OutOfMemoryError障害から回復する必要があるアプリケーションがあります。シングルスレッドプログラムでは常に機能しますが、マルチスレッドプログラムでは機能しない場合があります。アプリケーションは自動化されたJavaテストツールであり、生成されたテストシーケンスをテストクラスで可能な限り最大の深さまで実行します。ここで、UIは安定している必要がありますが、テストケースのツリーを拡大しているときにテストエンジンがメモリ不足になる可能性があります。私はこれを、テストエンジンの次の種類のコードイディオムで処理します。

ブールisOutOfMemory = false; //レポートに使用されるフラグ
{を試す
   SomeType largeVar;
   //ますますlargeVarに割り当てるメインループ
   // OKを終了するか、OutOfMemoryErrorを発生させる
}
catch(OutOfMemoryError ex){
   // largeVarはスコープ外になり、ゴミになる
   System.gc(); // largeVarデータをクリーンアップします
   isOutOfMemory = true; //使用可能なフラグ
}
//プログラムは回復を報告するフラグをテストします

これは、シングルスレッドアプリケーションでは常に機能します。しかし最近、テストエンジンをUIとは別のワーカースレッドに配置しました。現在、メモリ不足はどちらかのスレッドで任意に発生する可能性があり、それをどのように捕捉するかは私にはわかりません。

たとえば、UIのアニメーションGIFのフレームが、制御できないSwingクラスによって舞台裏で作成された独自のスレッドによって循環されているときにOOMEを発生させました。必要なすべてのリソースを事前に割り当てていると思っていましたが、アニメーターが次の画像を取得するたびにメモリを割り当てていることは明らかです。誰かが任意のスレッドで発生したOOMEを処理する方法についてのアイデアを持っているなら、私は聞いてみたいです。


シングルスレッドアプリでは、作成によってエラーがスローされた問題のある新しいオブジェクトの一部を使用しなくなった場合、それらはcatch句に収集される可能性があります。ただし、JVMがオブジェクトが後で使用される可能性があることを検出した場合、そのオブジェクトを収集できず、アプリが爆発します。このスレッドで私の答えを見てください。
ミスタースミス

4

OOMEはキャッチできますが、キャッチに達したときにJVMがいくつかのオブジェクトをガベージコレクションできるかどうか、およびその時点で残っているヒープメモリの数に応じて、通常は役に立たなくなります。

例:私のJVMでは、このプログラムは最後まで実行されます。

import java.util.LinkedList;
import java.util.List;

public class OOMErrorTest {             
    public static void main(String[] args) {
        List<Long> ll = new LinkedList<Long>();

        try {
            long l = 0;
            while(true){
                ll.add(new Long(l++));
            }
        } catch(OutOfMemoryError oome){         
            System.out.println("Error catched!!");
        }
        System.out.println("Test finished");
    }  
}

ただし、catchに1行追加するだけで、私が話していることがわかります。

import java.util.LinkedList;
import java.util.List;

public class OOMErrorTest {             
    public static void main(String[] args) {
        List<Long> ll = new LinkedList<Long>();

        try {
            long l = 0;
            while(true){
                ll.add(new Long(l++));
            }
        } catch(OutOfMemoryError oome){         
            System.out.println("Error catched!!");
            System.out.println("size:" +ll.size());
        }
        System.out.println("Test finished");
    }
}

キャッチに到達すると、JVMはリストが使用されなくなることを検出するため、正常に実行されます(この検出は、コンパイル時に行われる最適化にもなります)。したがって、printステートメントに到達すると、ヒープメモリはほぼ完全に解放されているので、操作を続行するための広いマージンがあります。これが最良のケースです。

ただし、llOOMEがキャッチされた後にリストが使用されるようにコードが配置されている場合、JVMはコードを収集できません。これは2番目のスニペットで発生します。新しいLong作成によってトリガーされたOOMEがキャッチされますが、すぐに新しいオブジェクト(System.out,println行の文字列)が作成され、ヒープがほぼいっぱいになり、新しいOOMEがスローされます。これは最悪のシナリオです。新しいオブジェクトを作成しようとして失敗し、OOMEをキャッチしましたが、新しいヒープメモリを必要とする最初の命令(たとえば、新しいオブジェクトの作成)が新しいOOMEをスローします。考えてみてください。メモリがほとんど残っていない状態で、この時点で他に何ができるでしょうか。たぶんただ存在します。したがって、役に立たない。

JVMがリソースを収集しない理由の1つは、恐ろしいことです。他のスレッドとの共有リソースもそれを利用しています。実験的なものではないアプリに挿入すると、脳のある人なら誰でもOOMEを捕まえることがいかに危険かがわかります。

Windows x86 32ビットJVM(JRE6)を使用しています。各Javaアプリのデフォルトのメモリは64MBです。


ll=nullキャッチブロックの内側にいる場合はどうなりますか?
Naanavanalla

3

OOMエラーをキャッチする理由を考えることができる唯一の理由は、もう使用していない大規模なデータ構造があり、nullに設定してメモリを解放できることです。しかし、(1)これはメモリを浪費していることを意味し、OOMEの後にただ足を引っ張るのではなく、コードを修正する必要があります。(2)キャッチしても、どうしますか?OOMはいつでも発生する可能性があり、すべてが半分完了している可能性があります。


3

質問2については、すでにBalusCが提案する解決策を見ました。

  1. java.lang.OutOfMemoryErrorをキャッチすることをお勧めする実際のシナリオはありますか?

私はちょうど良い例に出くわしたと思います。awtアプリケーションがメッセージをディスパッチすると、キャッチされていないOutOfMemoryErrorがstderrに表示され、現在のメッセージの処理が停止します。しかし、アプリケーションは実行し続けます!ユーザーは、舞台裏で発生している深刻な問題を認識せずに、他のコマンドを発行できます。特に彼が標準エラーを観察できない、または観察しない場合。したがって、oom例外をキャッチし、アプリケーションの再起動を提供する(または少なくとも提案する)ことが望まれます。


3

OutOfMemoryErrorをキャッチすることが理にかなっていて、機能しているように見えるシナリオがあります。

シナリオ:Androidアプリで、複数のビットマップを可能な限り高い解像度で表示し、それらを滑らかにズームできるようにしたいと考えています。

滑らかなズームのため、ビットマップをメモリに入れたいと思います。ただし、Androidではメモリに制限があり、デバイスに依存し、制御が困難です。

この状況では、ビットマップの読み取り中にOutOfMemoryErrorが発生する可能性があります。ここでは、それをキャッチしてから、低い解像度で続行すると役立ちます。


0
  1. 「良い」をどのように定義するかによります。私たちはバグのあるWebアプリケーションでそれを行い、ほとんどの場合機能します(ありがたいOutOfMemoryことに、無関係な修正により、今は起こりません)。ただし、それをキャッチしても、いくつかの重要なコードが壊れている可能性があります。複数のスレッドがある場合、それらのいずれかでメモリ割り当てが失敗する可能性があります。したがって、アプリケーションによっては、不可逆的に壊れる可能性が10〜90%あります。
  2. 私が理解している限り、途中でスタックを巻き戻すと、非常に多くの参照が無効になり、そのため、気にする必要のない多くのメモリを解放します。

編集:私はあなたがそれを試してみることをお勧めします。たとえば、徐々にメモリを割り当てる関数を再帰的に呼び出すプログラムを作成します。キャッチOutOfMemoryErrorし、あなたが有意義にその時点から続行できるかどうかを確認します。私の経験によれば、あなたはそれを行うことができますが、私の場合、それはWebLogicサーバーの下で起こったので、何らかの黒魔術が関与していたかもしれません。


-1

Throwableの下で何でもキャッチできます。一般的に言えば、RuntimeExceptionを除くExceptionのサブクラスのみをキャッチする必要があります(開発者の大部分はRuntimeExceptionもキャッチしますが、これは言語設計者の意図ではありませんでした)。

OutOfMemoryErrorをキャッチする場合、いったい何をしますか?VMのメモリが不足しています。基本的に、実行できるのは終了することだけです。メモリが不足していることを通知するダイアログボックスを開くこともできないでしょう。

VMは、メモリが完全になくなるとOutOfMemoryErrorをスローし(実際、すべてのエラーは回復不可能な状況を示すはずです)、それに対処するために実際にできることは何もないはずです。

すべきことは、メモリが不足している理由を調べ(NetBeansのプロファイラのようにプロファイラを使用する)、メモリリークがないことを確認することです。メモリリークがない場合は、VMに割り当てるメモリを増やします。


7
あなたの投稿が永続化するという誤解は、OOMがJVMのメモリ不足を示しているということです。代わりに、JVMは指示されたすべてのメモリを割り当てることができなかったことを実際に示しています。つまり、JVMに10Bのスペースがあり、100Bのオブジェクトを「更新」すると失敗しますが、向きを変えて5Bのオブジェクトを「更新」して正常に動作する可能性があります。
Tim Bender

1
そして、私が5Bしか必要としなかった場合、なぜ10Bを要求するのですか?試行錯誤に基づいて割り当てを行っている場合、それは間違っています。
TofuBeer 2010

2
Timは、OutOfMemoryの状況でも作業を実行できることを意味していたと思います。たとえば、ダイアログを開くのに十分なメモリが残っている可能性があります。
Stephen Eilert
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.