入力中の回答があります。ページを離れますか?※ページを離れると、回答が消えてしまいますページを離れるA回答を続ける入力中のお礼があります。任意のオブジェクトの実行中のヒープサイズを取得する方法を教えてください。具体的には、Undoバッファ(LinkedList)を実装していて、そのヒープサイズがあるサイズを超えた場合には、HDDに内容を保存してヒープを開放したいと考えています。これを実現するために、動的にヒープサイズを取得する必要があるのですが、また、上記のようにListがあるサイズを超えたら自動的にHDDなどに保存・呼び出しをしてくれてユーザレベルでオンメモリがどうか等を意識しなくてもすむようなライブラリは存在しないでしょうか?以上2点について、よろしくお願いします。通報するこの質問への回答は締め切られました。テスト」に関するQ&A:Vアプリでのテストに関して。17:30ANo.6で挙げられたふたつの条件に加えて、(3)OutOfMemoryErrorが起こりうるすべてのコードが、OutOfMemoryErrorが発生し処理が中断しても不整合が生じないように設計されていることという条件が必要だと思います。なければOutOfMemoryErrorが発生したそのオブジェクトは壊れているとみなさざるを得ません。発生しても、それは予期された動作ですからArrayListは壊れていませんが、OutOfMemoryErrorが起きたらそのArrayListは壊れていて、もはや使い物にならないとみなしたほうがいいでしょう。JavaのAPIにもOutOfMemoryErrorを予期しているメソッドほとんどないです。その大半が使えないでしょう。「すべてのオブジェクトは、OutOfMemoryErrorが起きた際にエラーハンドリングが可能であるくらいに、サイズが大きくなければならない」という奇妙な制限を加えてまでその方法をとる利点はないと思います。JavaのAPIの大半は小さなオブジェクトをアロケートする可能性があるので、使用を避けねばならなくなります。>事前に大きなヘッジメモリをアロケートしておいて、OOME時にそれを解放します。そのような方法でなんとかエラーのハンドリングできるとしても、エラーメッセージを表示したりエラーログを残すぐらいがせいぜいでしょう。不整合な状態になっている可能性がありますから、そのようなアプリケーションの実行を続けるのは危険です。壊れたデータで大切なファイルを上書きしてしまうといった取り返しのつかないことをしてしまう前に、アプリケーションを終了してしまったほうが安全でしょう。>「メモリウォッチャースレッド」を動かす技法>SoftReferenceやWeakReferenceそうですね。質問者のかたの要件には合いませんけれど、キャッシュを実現するならそれらが適当だと思います。これらに比べれば、OutMfMemoryErrorのcatchなど冗談もいいところです。>アプリケーションの設計を見直す(もっとメモリセーフな設計にする)それが可能なら最初からその設計をするべきです。OutMfMemoryErrorのcatchなどせず、最初から安全な設計にすべきだと自分は言っているわけです。>OOMEで単純にアプリケーションを終わらせる、などの結論になるでしょう。その結論では質問者のかたが困ってしまいますよ。>実例として具体的にご紹介できるオープンソースのソフト等は、今の私の知識内にはありません。残念です......。予期しているメソッドやcatchしているコードは見つかりました。classpthのjava.lang.reflect.Array#newInstance()がOutOfMemoryErrorを投げることがドキュメントに書かれていました。OutOfMemoryErrorを投げるために使われていることが多いようです。OutOfMemoryErrorのハンドリングは難しいからでしょう。18:46たしかに、hirusagariさんがおっしゃるように、どんな技法にも...コンピュータやプログラミングに限らず...その技法が有効に使えるための前提条件がありますね。「OutOfMemoryErrorをcatchする」に関しては、(1)もれなく確実にcatchできること、と、(2)そのときに、有意義な処理ができる程度のメモリ残量があることが、基本的な前提条件です。これらの前提条件は、大きなデータオブジェクトを単純にアロケートしていくだけのアプリケーションでは、通常、満たされます。Pitfallsで紹介されて以来、ときどき見かける(私も書いたことがある!)コードですが、実例として具体的にご紹介できるオープンソースのソフト等は、今の私の知識内にはありません。上の(1)の条件が満たされない場合、つまりOOMEが不特定多数の場所で予測不能に起こりうる場合には、独立のバックグラウンドスレッドとして「メモリウォッチャースレッド」を動かす技法があります。これは、一定の閾値(たとえば5メガバイト)を決めておいて、空きメモリの大きさがそれを下回ったら適切な対策を取ります(たとえば大きなデータ構造をclearする)。(2)の条件が満たされない、つまりOOMEが起きたときメモリの余裕がない場合は、「ヘッジング」という技法がよく使われます。いわゆる、“ヘッジファンド”の“ヘッジ”です。事前に大きなヘッジメモリをアロケートしておいて、OOME時にそれを解放します。ヘッジを取り崩すわけですね。Eclipseが、この技法を使っているようです。適切な対策を実行したあとで、ヘッジを再びアロケートしなければなりません。OOME対策として上の三つの技法が使えない状況では、これまたよく見かける方法ですが、データオブジェクト(等)のパーシステンス化(バックアップ)は早期にやっておいて、それらのオブジェクトの参照をSoftReferenceやWeakReferenceに変えます。WeakReferenceを使っているMapであるjava.util.WeakHashMapを、便利に使えるアプリケーションもあるでしょう。以上のどれも不可能なら、アプリケーションの設計を見直す(もっとメモリセーフな設計にする)、あるいは、OOMEで単純にアプリケーションを終わらせる、などの結論になるでしょう。17:02本項の質問文にあるように「HDDに内容を保存してヒープを開放したい」わけですから、OutOfMemoryErrorが起きたときに簡単なログを残すサンプルを書いてみます。XP上のJRE1.6.0_01で実行してみました。するところで再びOutOfMemoryErrorが発生し終了しました。書き換えて実行するとcatchで復旧しそのまま実行を続けられます。失敗したとき、まだある程度のメモリが残されているためですね。できないくらいのまさに「ギリチョンのメモリ貧乏」になってしまいます。少量メモリを確保したときに運悪くOutOfMemoryErrorが発生すると落ちます。自分ならそのようなコーディングを避けると思います。従ってOutOfMemoryErrorはコードのあらゆる位置で発生するおそれがありますから、Undo/Redoの部分だけOutOfMemoryErrorをcatchしてもザル同然です。自分の考えではそれはとてつもなく厄介なコーディングになる思います。>多くの実用アプリでよく使われているよろしかったらどのアプリケーションで使われているか教えていただけませんか?ソースが公開されているものでしたら幸いです。そのようなアプリケーションのコードがどうやって安定してOutOfMemoryErrorに対処しているのか学びたいと思いますので。11:28OutOfMemoryErrorをcatchしてメモリを解放するやりかたで、実用的/経験的にはOKですし、多くの実用アプリでよく使われている技法です。理由は、(1)物理的明示的にオンメモリの存在がはっきりしているリソースを解放するから、そして、(2)通常は、JVMがまったく何もできなくなるほどギリチョンのメモリ貧乏になることはないからです。あなたのアプリの実際のニーズや実行シナリオに即して、下のようなテストプログラムを書いて動かしてみてください。>Instrumentationのインスタンスの取得の方法がわかりませんでした。#2で挙げたページに次のような記述があるのでお読みになりましたよね。