home

OQL in MAT

11 June 2012 - Shanghai

前言

本文基于MAT 1.1.1编写

OQL

MAT 有内置的对象查询语言(OQL), OQL是类SQL风格的语句, 用来查询heap堆栈. 拿OQL和SQL比较, classes相当于tables, objects相当于rows, fields相当于columns. 因此OQL的基本语法像这样: SELECT * FROM [ INSTANCEOF ] [ WHERE ]

SELECT子句

SELECT子句决定查看对象的内容. 使用星号(*)返回Class Name(点击后浏览outgoing引用), Shallow Heap, Related Heap, 比如: SELECT * FROM java.lang.String SELECT * FROM java.lang.Class

指定显示内容

或者,可以指定显示内容: SELECT toString(s), s.count, s.value, s.@usedHeapSize, s.@retainedHeapSize, s.@GCRootInfo FROM java.lang.String s

SELECT s.getValueAt(2) FROM int[] s WHERE (s.@length > 2)

我碰到的案例, 查询对象TcpSocketReceiver内成员变量m_queue(LinkedBlockingQueue)的大小: SELECT s.m_queue.count.value FROM com.dianping.cat.message.io.TcpSocketReceiver s

指定显示列名

使用AS给列命名: SELECT toString(s) AS Value, s.@usedHeapSize AS “Shallow Size”, s.@retainedHeapSize AS “Retained Size” FROM java.lang.String s

结果去重

使用DISTINCT对结果对象去重: SELECT DISTINCT * FROM OBJECTS 0,1,1,2

使用DISTINCT OBJECTS: SELECT DISTINCT OBJECTS classof(s) FROM java.lang.String s 函数classof返回类对象. 当然所有的String对象返回相同的类对象. OBJECTS把classof返回的结果行转换成String对象.

FROM子句

FROM子句定义操作的类.

指定类

可以通过不同途径指定类:

通过类名:

SELECT * FROM java.lang.String

通过类名的正则表达式:

SELECT * FROM "java\.lang\..*"

通过子查询:

SELECT * FROM ( SELECT *
	FROM java.lang.Class c
	WHERE c implements org.eclipse.mat.snapshot.model.IClass )

包含子类

使用INSTANCEOF查询包含子类的对象(坑爹的, INSTANCEOF后面不能用接口类): SELECT * FROM INSTANCEOF java.lang.ref.Reference 返回的结果里包含了WeakReference和SoftReference的对象, 因为它们都继承自java.lang.ref.Reference. 我经常用INSTANCEOF来查询抽象类有哪些实例.

WHERE子句

WHERE子句指定搜索条件, 这样可以去除查询结果里不需要的数据.

运算符

下面的运算符按照优先顺序排列:

关系运算符

=, <=, >, <, [ NOT ] LIKE, [ NOT ] IN . SELECT * FROM java.lang.String s WHERE s.count >= 100 SELECT * FROM java.lang.String s WHERE toString(s) LIKE “.*day” SELECT * FROM java.lang.String s WHERE s.value NOT IN dominators(s)

相等运算 符

=, != SELECT * FROM java.lang.String s WHERE toString(s) = “monday”

AND条件运算符

SELECT * FROM java.lang.String s WHERE s.count > 100 
	AND s.@retainedHeapSize > s.@usedHeapSize

OR条件运算符

SELECT * FROM java.lang.String s WHERE s.count > 1000 
	OR s.value.@length > 1000

这些运算符可作用于表达式, 常量和子查询.

常量表达式

Boolean, String, Integer, Long and null literals: SELECT * FROM java.lang.String s WHERE ( s.count > 1000 ) = true WHERE toString(s) = “monday” WHERE dominators(s).size() = 0 WHERE s.@retainedHeapSize > 1024L WHERE s.@GCRootInfo != null

References

Eclipse Memory Analyzer Version 1.1.1 -> help content -> Reference -> OQL Syntax visualvm oql

Fork me on GitHub