目次

OQLとは

簡単に言うと

OQLは特定のクラスオブジェクト検索を行えるものです。

もう少し細かくいうと

オブジェクト問い合わせ言語 (オブジェクトといあわせげんご、オブジェクト照会言語、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ヒープから必要な情報を選択したり、フィルターしたりすることができます。

目的

メモリリーク解析のため、ヒープのスナップショットをとって、ビューアでみることまでできたが、インスタンスがたくさんありすぎる。

見つけたいのは、循環参照しているインスタンスだ。

それを絞り込むのに、OQLってつかえるの?っておもって情報を集めるというのが、このページの目的

select文の文法

OQLは、JavaScrip?埋め込み型言語(JavaScript? Expression Language)をベースとしています。

select <JavaScript expression to select>
  [ from [instanceof] <class name> <identifier>
  [ where <JavaScript boolean expression to filter> ] 

逆引き

自分では、まだ、問い合わせ文をつくれないので、サイトに掲載されている例文をまとめてみます。

注意点

ただし、これらのクエリーは発展途上なので、安定してるという保証はありません。

たとえば、下記のサンプルで、

Fileオブジェクトの持っている path フィールドの中身の値を一覧で表示

というのがありますが、実際に、jvisualvm.exeでやってみると、

OKselect x from java.io.File x
OKselect x.path from java.io.File x
ERRORselect x.path.value from java.io.File x
javax.script.ScriptException: sun.org.mozilla.javascript.internal.WrappedException: Wrapped java.lang.reflect.UndeclaredThrowableException

でした。

新しいバージョンをつかいましょう

あたらしいプラグインをjvisualvmでとりこもうとしたら、

あなたのjvisualvmは古いので、このプラグインは取り込めません的なメッセージがでてきた。

たしかに、バージョンふるいかもしれない。Java7がでているのに、Java6のjvisualvmつかっている自分がいけないのかもしれない。

だから、あたらしい、バージョンのJavaをダウンロードしてきてそのなかのツールを使うようにしてみたら、新しいプラグインを取り込めていいかもしれないです。

100文字以上のString を保持しているオブジェクトを検索したい

SELECT s FROM java.lang.String s WHERE (s.count >= 100)

文字列を正規表現で検索

select {instance: s, content: s.toString()} from java.lang.String s
   where /java/(s.toString())

部分文字列で検索

select toHtml(x)+" "+x.toString() from java.lang.String x where x.count>10 &&

x.toString().substring(0,5)=="<html"

Fileオブジェクトの持っている path フィールドの中身の値を一覧で表示

select file.path.value.toString() from java.io.File file

クラスローダの一覧を表示させたい

SELECT classof(cl).name  FROM INSTANCEOF java.lang.ClassLoader cl

配列の要素数が256以上あるインスタンスを調べたい

select a from int[] a where a.length >= 256

継承したクラスの一覧を表示

例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()

継承をしているクラスを列挙

select heap.findClass("java.io.BufferedInputStream").superclasses()

Returns whether two given Java objects are identical or not.

select identical(heap.findClass("Foo").statics.bar, heap.findClass("AnotherClass").statics.bar)

だれか訳して

IDを表示

select objectid(o) from java.lang.Object o

IDでインスタンスを検索

0xd404b198 の場合

select o from instanceof 0xd404b198 o

または

select heap.findObject("0xd404b198")

任意のクラスの任意のstaticメソッドを検索

例:"java.lang.System"でstaticsなpropsメソッドの場合

select heap.findClass("java.lang.System").statics.props

任意のクラスの任意のメソッドを検索

例:"java.lang.System"でpropsメソッドの場合

select heap.findClass("java.lang.System").props

任意のクラスのフィールド数を取得

例:"java.lang.System"の場合

select heap.findClass("java.lang.String").fields.length

到達可能なオブジェクトを列挙したい

select reachables(p) from java.util.Properties p

到達可能なオブジェクトを列挙するが、指定したメソッドからの到達は削除したい

select reachables(u, 'java.net.URL.handler') from java.net.URL u

複数のフィールドを表示

 select { name: t.name? t.name.toString() : "null", thread: t }      from instanceof java.lang.Thread t

参照数を表示したい

select count(referrers(o)) from java.lang.Object o

参照しているオブジェクト一覧がほしい

select referrers(f) from java.io.File f

指定回数以上参照されている任意のオブジェクトを一覧をだす

 select u from java.net.URL u where count(referrers(u)) > 2

参照しているフィールド一覧を得る

select referees(heap.findClass("java.io.File"))

任意の名前のクラス一覧を正規表現で取得

select filter(heap.classes(), "/java.net./(it.name)")

指定したオブジェクトが使っているメモリを調べる

select sizeof(o) from int[] o

注意!時間がかかる:関連するオブジェクトのメモリを集計する

select rsizeof(o) from instanceof java.lang.HashMap o

結果をHTMLフォーマットで返す

 select "<b>" + toHtml(o) + "</b>" from java.lang.Object o

弱参照しているもの一覧

select f.referent from java.lang.ref.SoftReference? f

   where f.referent != null

finalizableなオブジェクト一覧

 select f.referent from java.lang.ref.Finalizer f
   where f.referent != null

Find all finalizable objects and approximate size of the heap retained because of those.

訳すの疲れた

詳しくは、ここみて

https://blogs.oracle.com/sundararajan/entry/querying_java_heap_with_oql

   select { obj: f.referent, size: sum(map(reachables(f.referent), "sizeof(it)")) }
   from java.lang.ref.Finalizer f
   where f.referent != null

集計関数を使った例

countとか、maxとか まとめるのめんどくさくなってきたので、

http://visualvm.java.net/oqlhelp.html

みてね。

複雑な例

クラスローダごとにヒストグラム出す

select map(sort(map(heap.objects('java.lang.ClassLoader'), 
  '{ loader: it, count: it.classes.elementCount }'), 'lhs.count < rhs.count'),
  'toHtml(it) + "<br>"')

クラスローダごとに、循環参照しているものをだしたい!

システムの変数を列挙します。

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;
           });

副問い合わせ

サブクエリー カラムの例

select role.name, (select u from User u where u = role.user) from Role role;

サブクエリー FROM句の例

SELECT t.name
FROM ( SELECT t FROM Tutors t WHERE t.salary > 300 ) r, r.students s
WHERE s.fee > 30

サブクエリー WHERE句の例

SELECT p.name 
FROM p in People 
WHERE not ( p.name in SELECT t.name FROM t in TAs )

比較演算

http://www.topazproject.org/trac/wiki/Topaz/Manual/Section11

長文例

こんな書き方ができるんやね。ってことでまとめてみる

java heap analysis with oql: Count unique strings

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;
   }
  }
 );

select sum(heap.objects("sun.util.calendar.ZoneInfo?"),"sizeof(it)")と同等

select 
  map(heap.objects("java.lang.String"),
    function tally(obj) { 
      if(typeof tally.total == 'undefined') {
        tally.total = 0; 
        tally.count = 0;
      } 
      tally.total += sum(map(reachables(obj), "sizeof(it)"));
      tally.count++;
      return tally.total/tally.count; 
    }
  );

リンク

IBM Netcool/Precision IP向けのOQL

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)利用方法

http://andbrowser.com/development/knowhow/289/eclipse-android-memory-leak-mat-oql/

memory leak in our Tomcat container

http://stackoverflow.com/questions/2692745/oql-query-to-find-all-instances-and-sub-instances-of-a-given-class-refered-to-fr

GQL リファレンス

https://blogs.oracle.com/poonam/resource/OQL.htm

JAVAのAPI DOC org.eclipse.mat.snapshot.OQL

http://help.eclipse.org/juno/ntopic/org.eclipse.mat.ui.help/doc/org/eclipse/mat/snapshot/OQL.html

トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS