本文基于MAT 1.1.1编写
MAT 有内置的对象查询语言(OQL), OQL是类SQL风格的语句, 用来查询heap堆栈.
拿OQL和SQL比较, classes相当于tables, objects相当于rows, fields相当于columns. 因此OQL的基本语法像这样:
SELECT * FROM [ INSTANCEOF ]
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子句定义操作的类.
可以通过不同途径指定类:
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子句指定搜索条件, 这样可以去除查询结果里不需要的数据.
下面的运算符按照优先顺序排列:
=, <=, >, <, [ 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”
SELECT * FROM java.lang.String s WHERE s.count > 100
AND s.@retainedHeapSize > s.@usedHeapSize
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
Eclipse Memory Analyzer Version 1.1.1 -> help content -> Reference -> OQL Syntax visualvm oql