質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

3回答

11989閲覧

OutOfMemoryErrorのcatch句内でなぜ処理できる?

moge

総合スコア13

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

2グッド

0クリップ

投稿2017/03/04 19:54

OutOfMemoryErrorのcatch句内でなぜ処理できる?

JavaSE8です。
ヒープを使い切ってOutOfMemoryErrorがでたのであれば新しいオブジェクトをインスタンス化できないのでは?と思ったのですがキャッチ句内でもインスタンス生成できることが疑問です。

アドバイスのほど宜しくお願いいたします。

i50, maisumakun👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

swordone

2017/03/05 00:16

具体的なコードを提示してください。
guest

回答3

0

OutOfMemoryErrorは、空いているメモリに対して、作成しようとするオブジェクトが大きい場合に発生します。空きがぴいたり0になったときではありません。newに失敗したときにそのオブジェクト分のメモリは確保されませんので、メモリはわずかながら空いている状態です。つまり、newに失敗したオブジェクトよりcatch句で生成するオブジェクトの方がサイズが小さければ作成できる場合があります。もし、空きがぎりぎりでオブジェクトを生成したり、同じぐらい大きなサイズのオブジェクトをcatch句で作成しようとすれば、再度OutOfMemoryErrorが発生します。

Java

1import java.util.List; 2import java.util.ArrayList; 3 4class OutMemoryTest { 5 public static void main(String[] args) { 6 System.out.println("[total] = [used] + [free] | [max]"); 7 List<int[][]> list = new ArrayList<>(); 8 try { 9 for (int i = 0; i < 1000; i++) { 10 list.add(new int[1000][1000]); 11 printMemory(); 12 } 13 } catch (OutOfMemoryError e) { 14 System.out.println("out of memory"); 15 printMemory(); 16 list.add(new int[1000][1000]); // 再度OutOfMemoryErrorが発生 17 } 18 printMemory(); 19 } 20 21 public static void printMemory() { 22 long total = Runtime.getRuntime().totalMemory(); 23 long free = Runtime.getRuntime().freeMemory(); 24 long max = Runtime.getRuntime().maxMemory(); 25 long use = total - free; 26 System.out.printf("%10d = %10d + %10d | %10d\n", 27 total, use, free, max); 28 } 29}

Runtime.getRuntime().〜Memory()はヒープのメモリではなくJava VMのメモリであり、参考程度です。正確なヒープメモリの本当の空き具合はGCの動作をみるためにjstatなどを使う必要があります。

投稿2017/03/05 01:02

raccy

総合スコア21733

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

GCをやって不要なメモリーを回収しきった際の残りのメモリーがRESTであったときRESTより大きなサイズを確保しようとして発生するのがOutOfMemoryErrorですが、当然ながら確保失敗なのでまだメモリーの残量がRESTのままの状態でエラー処理が始まります。

ゆえにcatch節でREST未満のメモリーはまだ確保できるわけです。

しかしながら巨大なメモリーを確保しようとしてこのエラーが発生するのではなく、少しずつメモリーを圧迫していきながら最後に(RESTが非常に小さな値のときに)止めのnewをしようとした場合、catch節で利用可能なメモリー残量が非常に小さいため小さなオブジェクトをnewしようとしても、それさえできないということが起こるかもしれません。そうした場合は正しい例外処理ができるとは期待できないでしょう。

しかしアプリケーションを設計するときそのような状況にはならないように「メモリー見積もりをしておく」ことが普通でしょうから、メモリーリークバグがない限りメモリー不足のリカバリーができないという状況には普通ならないと思います。

投稿2017/03/05 00:57

編集2017/03/05 14:20
KSwordOfHaste

総合スコア18392

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

すでに出ている回答のほかに考えられることとして…
0. tryブロックの中でのみ有効な変数がある
tryを抜ければそれらはGC対象になるので、新たなインスタンス用のメモリを確保できる可能性がある
0. OutOfMemoryの原因が再帰メソッドのオーバーフロー
OutOfMemoryErrorが出てメソッドから抜けるとメソッドが確保していたヒープメモリが解放される

いずれにせよ、Errorなのでキャッチすべきではないのですがね。

投稿2017/03/06 01:15

swordone

総合スコア20649

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問