• 締切済み

オブジェクトのヒープサイズの取得

_ranco_の回答

  • _ranco_
  • ベストアンサー率58% (126/214)
回答No.6

たしかに、hirusagariさんがおっしゃるように、どんな技法にも…コンピュータやプログラミングに限らず…その技法が有効に使えるための前提条件がありますね。「OutOfMemoryErrorをcatchする」に関しては、(1)もれなく確実にcatchできること、と、(2)そのときに、有意義な処理ができる程度のメモリ残量があることが、基本的な前提条件です。これらの前提条件は、大きなデータオブジェクトを単純にアロケートしていくだけのアプリケーションでは、通常、満たされます。西暦2000年出版のJava Pitfallsで紹介されて以来、ときどき見かける(私も書いたことがある!)コードですが、実例として具体的にご紹介できるオープンソースのソフト等は、今の私の知識内にはありません。 そして、上の(1)の条件が満たされない場合、つまりOOMEが不特定多数の場所で予測不能に起こりうる場合には、独立のバックグラウンドスレッドとして「メモリウォッチャースレッド」を動かす技法があります。これは、一定の閾値(たとえば5メガバイト)を決めておいて、空きメモリの大きさがそれを下回ったら適切な対策を取ります(たとえば大きなデータ構造をclearする)。 また、(2)の条件が満たされない、つまりOOMEが起きたときメモリの余裕がない場合は、「ヘッジング」という技法がよく使われます。いわゆる、“ヘッジファンド”の“ヘッジ”です。事前に大きなヘッジメモリをアロケートしておいて、OOME時にそれを解放します。ヘッジを取り崩すわけですね。Eclipseが、この技法を使っているようです。もちろん、適切な対策を実行したあとで、ヘッジを再びアロケートしなければなりません。 OOME対策として上の三つの技法が使えない状況では、これまたよく見かける方法ですが、データオブジェクト(等)のパーシステンス化(バックアップ)は早期にやっておいて、それらのオブジェクトの参照をSoftReferenceやWeakReferenceに変えます。WeakReferenceを使っているMapであるjava.util.WeakHashMapを、便利に使えるアプリケーションもあるでしょう。 以上のどれも不可能なら、アプリケーションの設計を見直す(もっとメモリセーフな設計にする)、あるいは、OOMEで単純にアプリケーションを終わらせる、などの結論になるでしょう。

関連するQ&A

  • java.util.Listのヒープサイズの取得

    オブジェクトのサイズを取得するメソッドとして、  java.lang.instrument.Instrumentation#getObjectSize があることは教わったのですが、なんと、このメソッドは参照先オブジェクトの サイズを調べてくれません。 ですから、私の環境では、Listに何のオブジェクトをaddしても、しなくても 24 が返ってくるだけでした。 どなたか、List内のオブジェクトの合計のヒープサイズを求めるライブラリもしくは、 リフレクションとInstrumentation#getObjectSizeを使った合計のヒープサイズを調べる 具体的な実装例をご存知の方はおられませんでしょうか? ( 前の質問は全く無関係な方向に進んでしまっていますので、   しばらく放置させていただきます。ご了承ください。)

  • 無効なオブジェクトライブラリ

    エクセルVBAにて、ソフトを作製しています。 急に「無効なオブジェクトライブラリです。または定義されていないオブジェクトへの参照を含んでいます」というエラーが出てくるようになり、すべてのプロシージャが実行出来ない状況に陥ってしまします。 そうなってしまったら、全て閉じて最終保存したところまで戻らなければならず、非常にイラつきます。 中身ですが、ユーザーフォームは特に使っておらず、Sheet内のフォームのコマンドボタン、またコントロール/ツールボックスからリストボックスとテキストボックスを使っています。 ソースの中身について ・SQL接続を使っています。 ・開く度にテキストボックスを複数削除し、所定位置に複数生成します。 リストボックスやテキストボックスのサイズ、位置等変更したら、このエラーに陥る傾向があります。 エラーに陥ったソースをエラーになる前のソースに追加しても、特に問題が起こりません。 エラーメッセージのヘルプを開こうとしても、表示されません。 これは一体なにが原因なのでしょうか? 条件がどうしてもつかめません。 参照設定についても特に参照できていないライブラリはありません。 宜しくお願いします。

  • SortedSetならぬSortedListの良い実装はありませんか

    「SortedSet」の重複を許さない制限を取り払ったクラス、(あえていうならば)「SortedList」なる高速な実装はないでしょうか。 頻繁に挿入と削除を繰り返すので、TreeSetのように木構造が望ましいのですが、自分でB木とか何とか木を実装するのも骨が折れるので、そのようなライブラリや、こうすれば簡単にできるよ!的なテクニックがあれば教えていただければと思います。 今はArrayListよりはLinkedListの方がましかなという理由でこんな感じで実装しています。 interface SortedList <E extends Comparable<E>> {  public void add(E v);  public boolean remove(E v);  public E get(int i); } class SortedLinkedList <E extends Comparable<E>>  extends LinkedList<E>  implements SortedList<E> {  public void add(E v) {   int i=0, size=size();   for(i=0; i<size; i++)    if(v.compareTo( get(i) )<0)     break;   add(i, v);  }  public boolean remove(E v) {   return super.remove(v);  }  public E get(int i) {   return get(i);  } }

    • ベストアンサー
    • Java
  • 画像ファイルをアップロードする前に縦横のサイズを取得

    ローカルに保存されている任意の画像を選択(input type=fileなどで) すると、テキストボックスにその画像の縦横サイズを表示するといった 事をやりたいのですが、Javascriptで実現可能でしょうか? img.src = "ファイルパス"; img.height; img.width; でサイズ取得は可能ですが、ファイルパスを直書きするのではなく、 あくまで、任意の画像を選択して取得したいです。 わかる方がいらっしゃいましたらご教授いただきたいと思います。 よろしくお願いします。

  • iPhoto Libraryのパッケージの内容

    iMac(OSX)を使っています。 iPhotoで読み込んだ写真は「ピクチャ」の中の 「iPhoto Library」に全て保存されていますが、 この「iPhoto Library」を右クリックして 「パッケージの内容を表示」すると、 「Library.iPhoto」と「Library6.iPhoto」といった 2つのフォルダが表示されます。 両方とも中身の写真は同じのようなので、片方を 削除しようかと思いますが、「情報を見る」で それぞれを比べて見ると少し違いがあります。 削除してはいけないような気がします。 「Library.iPhoto」のほうはサイズ22バイトで 「Library6.iPhoto」は12バイトとなっています。 ちなみに、外付HDDにもコピーしてますので、 同様に同じ物が2つ存在しています。 何かの手違いで2つ出来てしまったのなら、 サイズの小さい「Library6.iPhoto」を削除しよう と思いますが大丈夫でしょうか?

    • ベストアンサー
    • Mac
  • Illustrator バイナリの外部ファイル出力

    Illustrator CS5 で JSX を使用して、以下の処理を書こうとしています。 (1) アクティブドキュメントから画像オブジェクトを取得 (2) 外部XMLファイルの要素内に、文字列として画像のバイナリを出力して保存 上記の処理を実現することはできるのでしょうか。 情報をなかなか見つけることができずに困っています。 よろしくお願いいたします。

  • Form オブジェクトの戻り値の設定

    はじめまして。Porome です。 Excel 2003 の VBA を使ってプログラミングをしています。 Form オブジェクトの戻り値の設定方法/受取方法について教えてください。 実装したいプログラムの概要は、以下の通りです。 標準モジュールに記載したサブルーチンから Form オブジェクトを 生成し、Form オブジェクトで入力されたデータを標準モジュール側 で取得する…というものです。 書きたいソースコードのイメージは以下の通りです。 Sub MySub1() dim i_Form As New MyForm1 dim i_Name As String dim i_Age As String dim i_Ret As Integer 'MyForm1OK, MyForm1Cancel が戻ってくるまで、じっと待つ i_Ret = i_Form.Show, vbModal Select Case i_Ret 'MyForm1 で OK ボタンが押された Case MyForm1OK: i_Name = i_Form1.txtName.Value i_Age = i_Form1.txtAge.Value MsgBox(i_Name & " さんの年齢は " & i_Age & " 歳です") 'MyForm1 で Cancel ボタンが押された Case MyForm1Cancel: MsgBox("処理はキャンセルされました") 'MyForm1 では、MyForm1 では、MyForm1OK, MyForm1Cancel 以外は '戻さない仕様とします。 Case Else '何もしない(ここには来てはいけない) End Select End Sub こういったことを実現するためには ・MyForm1 では、 OK ボタンを押したら、MyForm1OK を Show メソッドの戻り値として セットし、処理を MySub1 に戻す Cancel ボタンを押したら、MyForm1Cancel を Show メソッドの戻り値としてセットし、処理を MySub1 に戻す OK ボタン、Cancel ボタン Click 以外の Form イベントでは、MyForm1 での処理が継続され、MySub1 は MyForm1 の戻り値(MyForm1OK/MyForm1Cancel)を、じっと待つ といったことが必要になってくるかと思います。 こういった処理を実装するには、呼び出し元 (MySub1)、呼び出し先 (MyForm1) では、それぞれどのようなコードを記載すればよろしいでしょうか? 説明が下手で申し訳ありませんが、アドバイスをお願いいたします

  • VBAでバイナリーデータを画像として貼り付けたい

    お世話になります。 現在、ExcelからOracleのデータベースを検索して値を選択→シートに張り付けて印刷する、請求書発行のプログラムを作っています。 そこで、実装方法が不明なところがでてきましたので、もしご存知の方は教えてください。 Oracleのデータベースには、Blob型のカラムに請求書発行元会社のロゴデータ(gif形式)が格納されていますが、これをExcelのシートに画像オブジェクトとして貼り付けようとしています。 Oracleのデータベースからの値の取得はできていて、これを画像オブジェクトとしてシートに貼り付ける方法をいろいろ試行錯誤しているのですが、いまだ実現できずにいます。 ※できれば、サンプルのプログラムも記載いただければ幸いです

  • [C言語]freeする領域のサイズは誰が管理?

    趣味でプログラミングの勉強をしています。 C言語で、ふと疑問に思いましたので質問させていただきます。 動的に領域を確保するときにはmalloc()にサイズを与えて、その領域のアドレスを取得します。 で、解放するときにはfree()に領域のアドレスを与えます。 ここで疑問に思ったのですが、領域を開放する場合にはその領域のアドレスとサイズが必要ではないかと思うのですが、free()ではアドレスしか与えませんよね? 誰かがアドレスとサイズが対になった情報を管理する必要があると思うのですが、誰が管理しているのでしょうか? 単純に考えてコンパイルしてできた実行形式のファイル中(あるいは呼ばれる外部ライブラリ?)にその機能があると思うのですが、それで合っていますか? よろしくお願いします。

  • CFileの使い方を教えてください

    環境はWIN98 VC++6.0 MFCです。 見よう見真似で以下のようにしたら、配列のデータがXXX.txtファイルに保存されました。 それじゃってことで、XXX.txtファイルからデータを取り出し、元通りに配列aa[n]に格納するにはどうすれば良いのですか? そう言うことはやれるのですか? void CAbcDlg::OnButton4() {  // TODO: この位置にコントロール通知ハンドラ用のコードを追加してください  CString str;  LPTSTR pszBuf;  long size;   CFile fpw( "XXX.txt", CFile::modeCreate | CFile::modeWrite | CFile::shareExclusive );   for(n=0;n<10;n++){    str=aa[n];    size = str.GetLength();    fpw.Write( &size, sizeof( long ) );    //バッファの確保    pszBuf = str.GetBuffer( size );   //書き込み    fpw.Write( pszBuf, size );   //バッファの開放   str.ReleaseBuffer();  } }