*目次 [#ae388f58] #contents *OQLとは [#o645a4c8] **簡単に言うと [#id1a71b2] OQLは特定のクラスオブジェクト検索を行えるものです。 ***もう少し細かくいうと [#h0f51ff3] オブジェクト問い合わせ言語 (オブジェクトといあわせげんご、オブジェクト照会言語、OQL、英: Object Query Language) は、Object Data Management Group (ODMG) に準拠したオブジェクトデータベースに対する問い合わせと更新を行うための宣言型の問い合わせ言語 (データベース言語) である。 OQLは、宣言型言語であり、手続き型言語ではない。 OQLは、関係データベース (リレーショナルデータベース) の問い合わせ言語 (データベース言語) SQL をもとにしている。 OQLは、ODMGによって開発され標準仕様として公開された。 ※Wikiより http://ja.wikipedia.org/wiki/%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E5%95%8F%E3%81%84%E5%90%88%E3%82%8F%E3%81%9B%E8%A8%80%E8%AA%9E なお、このページでは扱うOQL (Object Query Language):は、Javaヒープの検索をするために利用できるSQLのような問い合わせ言語です。OQLはJAVAヒープから必要な情報を選択したり、フィルターしたりすることができます。 *目的 [#pa7d91f5] メモリリーク解析のため、ヒープのスナップショットをとって、ビューアでみることまでできたが、インスタンスがたくさんありすぎる。 見つけたいのは、循環参照しているインスタンスだ。 それを絞り込むのに、OQLってつかえるの?っておもって情報を集めるというのが、このページの目的 *select文の文法 [#vc34f018] OQLは、JavaScrip埋め込み型言語(JavaScript Expression Language)をベースとしています。 select <JavaScript expression to select> [ from [instanceof] <class name> <identifier> [ where <JavaScript boolean expression to filter> ] *逆引き [#f521a7ba] 自分では、まだ、問い合わせ文をつくれないので、サイトに掲載されている例文をまとめてみます。 ただし、これらのクエリーは発展途上なので、安定してるという保証はありません。 たとえば、下記のサンプルで、 Fileオブジェクトの持っている path フィールドの中身の値を一覧で表示 というのがありますが、実際に、jvisualvm.exeでやってみると、 |OK|select x from java.io.File x| |OK|select x.path from java.io.File x| |ERROR|select x.path.value from java.io.File x| javax.script.ScriptException: sun.org.mozilla.javascript.internal.WrappedException: Wrapped java.lang.reflect.UndeclaredThrowableException でした。 **100文字以上のString を保持しているオブジェクトを検索したい [#oe76cd46] SELECT s FROM java.lang.String s WHERE (s.count >= 100) **文字列を正規表現で検索 [#jb8aba98] select {instance: s, content: s.toString()} from java.lang.String s where /java/(s.toString()) **Fileオブジェクトの持っている path フィールドの中身の値を一覧で表示 [#a6fbd74f] select file.path.value.toString() from java.io.File file **クラスローダの一覧を表示させたい [#v296c22a] SELECT classof(cl).name FROM INSTANCEOF java.lang.ClassLoader cl **配列の要素数が256以上あるインスタンスを調べたい [#cee9f8c4] select a from int[] a where a.length >= 256 **継承したクラスの一覧を表示 [#xd652cd8] 例1 select classof(o).name from instanceof java.lang.ref.Reference o 例2 SELECT ac FROM INSTANCEOF android.app.Activity ac 例3 select heap.findClass("java.io.InputStream").subclasses() **継承をしているクラスを列挙 [#ycbe3e00] 例 select heap.findClass("java.io.BufferedInputStream").superclasses() **Returns whether two given Java objects are identical or not. [#pe09055e] select identical(heap.findClass("Foo").statics.bar, heap.findClass("AnotherClass").statics.bar) だれか訳して **IDを表示 [#y7ddcc73] select objectid(o) from java.lang.Object o **IDでインスタンスを検索 [#edd08720] 0xd404b198 の場合 select o from instanceof 0xd404b198 o または select heap.findObject("0xd404b198") **任意のクラスの任意のstaticメソッドを検索 [#j0e93bed] 例:"java.lang.System"でstaticsなpropsメソッドの場合 select heap.findClass("java.lang.System").statics.props **任意のクラスの任意のメソッドを検索 [#a17a6696] 例:"java.lang.System"でpropsメソッドの場合 select heap.findClass("java.lang.System").props **任意のクラスのフィールド数を取得 [#v845f6bb] 例:"java.lang.System"の場合 select heap.findClass("java.lang.String").fields.length **到達可能なオブジェクトを列挙したい [#obff0cb1] select reachables(p) from java.util.Properties p **到達可能なオブジェクトを列挙するが、指定したメソッドからの到達は削除したい [#f4d207b5] select reachables(u, 'java.net.URL.handler') from java.net.URL u **複数のフィールドを表示 [#fed317bd] select { name: t.name? t.name.toString() : "null", thread: t } from instanceof java.lang.Thread t **参照数を表示したい [#j928fa82] select count(referrers(o)) from java.lang.Object o **参照しているオブジェクト一覧がほしい [#h7502111] select referrers(f) from java.io.File f **指定回数以上参照されている任意のオブジェクトを一覧をだす [#x7acdb31] select u from java.net.URL u where count(referrers(u)) > 2 **参照しているフィールド一覧を得る [#mbe6e2ad] select referees(heap.findClass("java.io.File")) **任意の名前のクラス一覧を正規表現で取得 [#odf722b9] select filter(heap.classes(), "/java.net./(it.name)") **指定したオブジェクトが使っているメモリを調べる [#v07de78b] select sizeof(o) from int[] o **注意!時間がかかる:関連するオブジェクトのメモリを集計する [#hf00c854] select rsizeof(o) from instanceof java.lang.HashMap o **結果をHTMLフォーマットで返す [#x1317c2e] select "<b>" + toHtml(o) + "</b>" from java.lang.Object o *集計関数を使った例 [#seea60a4] countとか、maxとか まとめるのめんどくさくなってきたので、 http://visualvm.java.net/oqlhelp.html みてね。 *複雑な例 [#ob6ca7c8] **クラスローダごとにヒストグラム出す [#e371e9e5] select map(sort(map(heap.objects('java.lang.ClassLoader'), '{ loader: it, count: it.classes.elementCount }'), 'lhs.count < rhs.count'), 'toHtml(it) + "<br>"') **クラスローダごとに、循環参照しているものをだしたい! [#ga3f1655] システムの変数を列挙します。 select map(filter(heap.findClass('java.lang.System').props.table, 'it != null && it.key != null && it.value != null'), function (it) { var res = it.key.toString() + ' = ' + it.value.toString(); return res; }); *長文例 [#nedbc942] こんな書き方ができるんやね。ってことでまとめてみる **java heap analysis with oql: Count unique strings [#p26d66b2] http://stackoverflow.com/questions/8242205/java-heap-analysis-with-oql-count-unique-strings var counts={}; var alreadyReturned={}; filter( sort( map(heap.objects("java.lang.String"), function(heapString){ if( ! counts[heapString.toString()]){ counts[heapString.toString()] = 1; } else { counts[heapString.toString()] = counts[heapString.toString()] + 1; } return { string:heapString.toString(), count:counts[heapString.toString()]}; }), 'lhs.count < rhs.count'), function(countObject) { if( ! alreadyReturned[countObject.string]){ alreadyReturned[countObject.string] = true; return true; } else { return false; } } ); *リンク [#e1be54b0] **IBM Netcool/Precision IP向けのOQL [#kbcdfaad] http://publib.boulder.ibm.com/infocenter/tivihelp/v8r1/index.jsp?topic=/com.ibm.netcool_precision.doc/pr35se/xF1118340.html **メモリリークを発見!Androidアプリのメモリ解析手法 その2 OQL (Object Query Language)利用方法 [#daae6f9b] http://andbrowser.com/development/knowhow/289/eclipse-android-memory-leak-mat-oql/ **memory leak in our Tomcat container [#x44ebb02] http://stackoverflow.com/questions/2692745/oql-query-to-find-all-instances-and-sub-instances-of-a-given-class-refered-to-fr **GQL リファレンス [#rabc9b3f] https://blogs.oracle.com/poonam/resource/OQL.htm **JAVAのAPI DOC org.eclipse.mat.snapshot.OQL [#z5d5891a] http://help.eclipse.org/juno/ntopic/org.eclipse.mat.ui.help/doc/org/eclipse/mat/snapshot/OQL.html