本文主要翻译自JDK 1.8的JVM监控工具jhat中关于OQL的英文帮助说明。
可以在jhat 和 jvisualvm 中进行实践。
OQL(对象查询语言)
OQL是用于查询Java堆的类SQL查询语言。OQL允许过滤/选择从Java堆中获取的信息。虽然HAT已经支持预定义的查询,例如“显示类X的所有实例”,但OQL增加了更多的灵活性。OQL基于JavaScript表达式语言。
OQL查询的形式select
[ from [instanceof]
[ where ] ]
解释:
(1)class name是java类的完全限定名,如:java.lang.String, java.util.ArrayList, [C是char数组, [Ljava.io.File是java.io.File[],依此类退
(2)类的完全限定名不足以唯一的辨识一个类,因为不同的ClassLoader载入的相同的类,它们在JVM中是不同类型的
(3)instanceof表示也查询某一个类的子类,如果不明确instanceof,则只精确查询class name指定的类
(4)from和where子句都是可选的
(5)可以使用obj.field_name语法访问Java字段,并且可以使用array [index]语法访问数组元素
OQL示例查询长度大于等于100的字符串select s from java.lang.String s where s.value.length >= 100
查询长度大于等于256的int数组select a from [I a where a.length >= 256
另一种方式:select a from int[] a where a.length >= 256显示与正则表达式匹配的字符串的内容select s.value.toString() from java.lang.String s
where /java/.test(s.value.toString())
/java/ 修改成你的正则表达式,如/^MyClass$/ 就会匹配MyClass这个字符串显示所有File对象的文件路径select file.path.value.toString() from java.io.File file
显示所有ClassLoader类的名称select classof(cl).name from instanceof java.lang.ClassLoader cl
显示由给定id字符串标识的Class的实例select o from instanceof 0x741012748 o
请注意,0x741012748是类的ID(在会话中)。通过查看该类页面中显示的id可以找到它。
OQL内置对象,函数
堆对象
该堆内置对象支持下列方法:heap.forEachClass
- 为每个Java类调用一个回调函数heap.forEachClass(callback);
heap.forEachObject
- 为每个Java对象调用回调函数heap.forEachObject(callback, clazz, includeSubtypes);clazz
是选择其实例的类。如果未指定,则默认为java.lang.Object。includeSubtypes
是一个布尔标志,指定是否包含子类型实例。该标志的默认值为true。
heap.findClass
- 查找给定名称的Java类heap.findClass(className);
whereclassName
是要查找的类的名称。生成的Class对象具有以下属性:name - 类的名称。
superclass - 超类的类对象(如果是java.lang.Object,则为null)。
statics - 类的静态字段的名称,值对。
fields - 字段对象的数组。field对象具有名称,签名属性。
loader - 加载此类的ClassLoader对象。
signers - 签署此类的签名者。
protectionDomain - 此类所属的保护域。
类对象具有以下方法:isSubclassOf - 测试给定的类是否是此类的直接或间接子类。
isSuperclassOf - 测试给定的Class是否是此类的直接或间接超类。
subclasses - 返回直接和间接子类的数组。
superclasses - 返回直接和间接超类的数组。