- PR -

インスタンスの使用メモリ測定方法

1
投稿者投稿内容
電気ひつじ
会議室デビュー日: 2003/01/15
投稿数: 8
投稿日時: 2003-01-15 12:31
任意のインスタンスとそのインスタンスから参照されている
インスタンスの合計メモリ使用量を測定するにはどうすれば
よいでしょうか?

現在はVMの空きメモリをインスタンスを操作する前後で取得
して空きメモリの差分で判断しています。
もっとスマートな方法がありましたらご教授ください。

Runtime rt = Runtime.getRuntime();
long freeMemory = rt.freeMemory();
さくらば
大ベテラン
会議室デビュー日: 2002/11/12
投稿数: 145
投稿日時: 2003-01-16 00:43
こんにちは。

引用:

電気ひつじさんの書き込み (2003-01-15 12:31) より:
任意のインスタンスとそのインスタンスから参照されている
インスタンスの合計メモリ使用量を測定するにはどうすれば
よいでしょうか?



一般的にはプロファイラで可能です。例えば、売っているものでは
Borland の OptimizeIt とか Sitraka の JProbe などがあります。

これらのツールはプログラムが動作しながらメモリを調べられます
が、それなりの値段になります。

OptimizeIt http://www.borland.co.jp/optimizeit/
JProbe http://www.sitraka.com/software/jprobe/

もしプログラムが終了したときにプロファイル結果を出力するよう
なものでかまわなければ java.exe に標準でついている hprof が
使えます。

コード:
    java -Xrunhprof [Class File]



hprof のヘルプは次のようにします。

コード:
    java -Xrunhprof:help



ただし、プロファイルの結果はかなり大きいファイルになるので、見る
のは大変です
英語なのですが、次の Web が参考になると思います。

http://developer.java.sun.com/developer/onlineTraining/Programming/JDCBook/perf3.html


unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2003-01-16 10:16
unibon です。こんにちわ。

引用:

電気ひつじさんの書き込み (2003-01-15 12:31) より:
任意のインスタンスとそのインスタンスから参照されている
インスタンスの合計メモリ使用量を測定するにはどうすれば
よいでしょうか?


グラフ(graph)理論における連結成分を抜き出すことに相当する、
と捉えて合っているでしょうか。
以下、思いついただけで試してはいませんが、
まず、準備としてメモリ使用量を測りたいクラスを
すべて implements Serializable します。
そして、実行時にいざメモリ使用量を測りたいインスタンスを、
メモリ上のストリーム(ファイルのストリームでもよいけど)にシリアライズして、
シリアライズした結果のバイト数を調べる、というのはどうでしょうか。
必ずしもメモリ上の使用量とは一致しないですし、
データ構造もメモリ上のものとは違いますが、
少なくともインスタンス間の関連は辿ることができているはずだし、
ツールが不要という手軽さがありそうです。
電気ひつじ
会議室デビュー日: 2003/01/15
投稿数: 8
投稿日時: 2003-01-17 14:27
さくらばさん、unibonさん、たいへん参考になりました。

今回の場合クラス数が多すぎるので、とりあえずJProbの体験版を使ってみることにしました。
残念ながら任意のインスタンスと連結成分の合計使用メモリ量は測定できないようですが
リアルタイムでメモリ使用状況や、呼び出し元メソッドを知ることができるので大変便利です。
ありがとうございました。
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2003-01-17 17:09
unibon です。自己フォローです。

引用:

unibonさんの書き込み (2003-01-16 10:16) より:
以下、思いついただけで試してはいませんが、
まず、準備としてメモリ使用量を測りたいクラスを
すべて implements Serializable します。


リフレクション(java.lang.reflect)を使えば、
ある指定されたインスタンスを起点として、
わりと"簡単"に、フィールドを列挙して
そのフィールドから関連をどんどん辿っていけそうな気がします。
Serializable と同じようなことをするだけですよね。
自分でやるので implements Serializable も要らないし。
そして、辿れたすべてのフィールドのデータサイズを合計するだけ。

どこかにそういうツールが公開されているかも、という期待もありますが、
探すよりも私などが自分で作ってみたほうが早いかもしれません。
#しかし、本当に"簡単"なのかどうかが分からない。
まりり
ぬし
会議室デビュー日: 2001/12/05
投稿数: 329
投稿日時: 2003-01-20 00:27
> リフレクション(java.lang.reflect)を使えば、
> ある指定されたインスタンスを起点として、
> わりと"簡単"に、フィールドを列挙して
> そのフィールドから関連をどんどん辿っていけそうな気がします。
> Serializable と同じようなことをするだけですよね。
> 自分でやるので implements Serializable も要らないし。
> そして、辿れたすべてのフィールドのデータサイズを合計するだけ。

この「データサイズ」を測る方法ってあります?
結局のところ実メモリとしてどれくらい占めてるかって把握できなさそうな。
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2003-01-20 11:27
unibon です。こんにちわ。

引用:

まりりさんの書き込み (2003-01-20 00:27) より:
> そして、辿れたすべてのフィールドのデータサイズを合計するだけ。

この「データサイズ」を測る方法ってあります?
結局のところ実メモリとしてどれくらい占めてるかって把握できなさそうな。


ちなみに私は、フィールドごとの C で言えば sizeof を足し算したもの(さらにパディングなし)を考えていて、
それ以外の要因によるメモリ消費は考えていません。
余談ですが、この単純な足し算を自分でやろうとしたら、
http://gimlay.org/~javafaq/S031.html#S031-03
のような問題があることが分かり、そこで詰まってしまいました(汗)。
すなわち private なフィールドにアクセスすると
IllegalAccessException が出てしまうのでした。
t-wata
大ベテラン
会議室デビュー日: 2002/07/12
投稿数: 209
お住まい・勤務地: 東京
投稿日時: 2003-01-20 12:32
Windowsをお使いでしたら、
http://www.geocities.com/moellep/debug/HeapInspector.html
こんなものもあります。
1

スキルアップ/キャリアアップ(JOB@IT)