温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

如何理解java中MAT对OQL的支持

发布时间:2021-09-27 09:53:33 来源:亿速云 阅读:243 作者:柒染 栏目:编程语言

这篇文章将为大家详细讲解有关如何理解java中MAT对OQL的支持,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。

MAT 支持一种类似于SQL的查询语言OQL(Object Query Language)。OQL使用类SQL语法,可以在堆中进行对象的查找和筛选。

1. Select子句

MAT中,Select子句的格式与SQL基本一致,用于指定要显示的列。Select子句中可以使用“*”,查看结果对象的引用实例(相当于outgoing references)。

select * from java.util.Vector v

以上查询的输出如图所示,在输出结果中,结果集中的每条记录都可以展开,查看各自的引用对象。

如何理解java中MAT对OQL的支持

OQL还可以指定对象的属性进行输出,下例输出所有Vector对象的内部数组,输出结果如图所示。使用“OBJECTS”关键字,可以将返回结果集中的项以对象的形式显示。

SELECT OBJECTS v.elementData FROM java.util.Vector v

如何理解java中MAT对OQL的支持

Select子句中,使用“AS RETAINED SET”关键字可以得到所得对象的保留集。下例得到jvm.chapter07.Student对象的保留集。

SELECT AS RETAINED SET * FROM jvm.chapter07.Student

如何理解java中MAT对OQL的支持

DISTINCT”关键字用于在结果集中去除重复对象。下例的输出结果中只有一条“class java.lang.String”记录。如果没有“DISTINCT”,那么查询将为每个String实例输出其对应的Class信息。

SELECT DISTINCT OBJECTS classof(s) FROM java.lang.String s

如何理解java中MAT对OQL的支持

2. From子句

From 子句用于指定查询范围,它可以指定类名、正则表达式或者对象地址。

下例使用From子句,指定类名进行搜索,并输出所有的java.lang.String实例。

SELECT * FROM java.lang.String s

下例使用正则表达式,限定搜索范围,输出所有java.lang包下所有类的实例,如图所示。

SELECT * FROM "jvm\.chapter07\..*"

如何理解java中MAT对OQL的支持

也可以直接使用类的地址进行搜索。使用类的地址的好处是可以区分被不同ClassLoader加载的同一种类型。下例中“0x37a014d8”为类的地址。

select * from 0x37a014d8

有多种方法可以获得类的地址,在 MAT 中,一种最为简单的方法如图所示。

如何理解java中MAT对OQL的支持

From子句中,还可以使用“INSTANCEOF”关键字,返回指定类的所有子类实例。下例的查询返回了当前堆快照中所有的抽象集合实例,包括java.util.Vectorjava.util.ArrayListjava.util.HashSet等。

SELECT * FROM INSTANCEOF java.util.AbstractCollection

From子句中,还可以使用“OBJECTS”关键字。使用“OBJECTS”关键字后,那么原本应该返回类的实例的查询,将返回类的信息。

SELECT * FROM OBJECTS java.lang.String

以上查询的返回结果如图所示。它仅返回一条记录,表示java.lang.String的类的信息。

如何理解java中MAT对OQL的支持

如果不使用“OBJECTS”关键字,这个查询将返回所有的java.lang.String实例:

如何理解java中MAT对OQL的支持

OBJECTS”关键字也支持与正则表达式一起使用。下面的查询,返回了所有满足给定正则表达式的所有类,其结果如图所示。

SELECT * FROM OBJECTS "jvm\.chapter07\..*"

如何理解java中MAT对OQL的支持

注意:在From子句中使用OBJECTS关键字,将返回符合条件的类信息,而非实例信息。这与Select子句中的OBJECTS关键字是完全不同的。

3. Where子句

Where子句用于指定OQL的查询条件。OQL查询将只返回满足Where子句指定条件的对象。Where子句的格式与传统SQL极为相似。

下例返回长度大于10的char数组。

SELECT * FROM char[] s WHERE s.@length>10

下例返回包含“java”子字符串的所有字符串,使用“LIKE”操作符,LIKE”操作符的操作参数为正则表达式

SELECT * FROM java.lang.String s WHERE toString(s) LIKE ".*java.*"

下例返回所有value域不为null的字符串,使用“=”操作符。

SELECT * FROM java.lang.String s where s.value!=null

Where子句支持多个条件的AND、OR运算。下例返回数组长度大于15,并且深堆大于1000字节的所有Vector对象。

SELECT * FROM java.util.Vector v WHERE v.elementData.@length>15 AND v.@retainedHeapSize>1000
4 内置对象与方法

OQL中可以访问堆内对象的属性,也可以访问堆内代理对象的属性。访问堆内对象的属性时,格式如下:

[ <alias>. ] <field> . <field>. <field>

其中alias为对象名称。

下例访问java.io.File对象的path属性,并进一步访问pathvalue属性。

SELECT toString(f.path.value) FROM java.io.File f

以上查询得到的结果如图所示。

如何理解java中MAT对OQL的支持

这些堆内对象的属性与Java对象一致,拥有与Java对象相同的结果。

MAT为了能快捷地获取堆内对象的额外属性(比如对象占用的堆大小、对象地址等),为每种元类型的堆内对象建立了相对应的代理对象,以增强原有的对象功能。访问代理对象的属性时,使用如下格式:

[ <alias>. ] @<attribute>

其中,alias为对象名称,attribute为属性名。

下例显示了String对象的内容、objectidobjectAddress

SELECT s.toString(), s.@objectId, s.@objectAddress FROM java.lang.String s

下例显示了File对象的对象ID、对象地址、代理对象的类型、类的类型、对象的浅堆大小以及对象的显示名称。

SELECT f.@objectId, f.@objectAddress, f.@class, f.@clazz, f.@usedHeapSize, f.@displayName FROM java.io.File f

下例显示java.util.Vector内部数组的长度。

SELECT v.elementData.@length FROM java.util.Vector v

下表整理了MAT代理对象的基本属性。

对象类型接口接口功能
基对象IObejctobjectId对象ID
基对象IObejctobjectAddress对象地址
基对象IObejctclass代理对象类型
基对象IObejctclazz对象类类型
基对象IObejctusedHeapSize浅堆大小
基对象IObejctretainedHeapSize深堆大小
基对象IObejctdisplayName显示名称
Class对象IClassclassLoaderIdClassLoad的ID
数组IArraylength数组长度
元类型数组IPrimitiveArrayvalueArray数组内容
对象数组IObjectArrayreferenceArray数组内容

除了使用代理对象的属性,OQL中还可以使用代理对象的方法,使用格式如下:

[ <alias> . ] @<method>( [ <expression>, <expression> ] )

下例显示int数组中索引下标为2的数据内容。

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

下例显示对象数组中索引下标为2的对象。

SELECT OBJECTS s.@referenceArray.get(2) FROM java.lang.Object[] s WHERE (s.@length > 2)

下例显示了当前堆中所有的类型。

select * from ${snapshot}.getClasses()

下例显示了所有的java.util.Vector对象及其子类型,它的输出如图所示。

select * from INSTANCEOF java.util.Vector

如何理解java中MAT对OQL的支持

下例显示当前对象是否是数组。

SELECT c, classof(c).isArrayType() FROM ${snapshot}.getClasses() c

代理对象的方法整理如表所示。

对象说明对象名对象方法对象方法说明
全局快照ISnapshotgetClasses()所有实例的集合
全局快照ISnapshotgetClassesByName(String name, boolean includeSubClasses)根据名称选取符合条件的实例
类对象IClasshasSuperClass()是否有超类
类对象IClassisArrayType()是否是数组
基对象IObjectgetObjectAddress()取得对象地址
元类型数组IPrimitiveArraygetValueAt(int index)取得数组中给定索引的数据
元类型数组,对象数组[] or Listget(int index)取得数组中给定索引的数据

MAT的OQL中还内置一些有用的函数,如表所示。

表 OQL中的内置函数

函数说明
toHex( number )转为16进制
toString( object )转为字符串
dominators( object )取得直接支配对象
outbounds( object )取得给定对象引用的对象
inbounds( object )取得引用给定对象的对象
classof( object )取得当前对象的类
dominatorof( object )取得给定对象的直接支配者

下例显示所有长度为15的字符串内容(JDK 1.7导出的堆)。

SELECT toString(s) FROM java.lang.String s WHERE ((s.value.@length = 15) and (s.value != null))

下例显示所有jvm.chapter07.Student对象的直接支配对象。即给定对象回收后,将释放的对象集合。

SELECT objects dominators(s) FROM jvm.chapter07.Student s

以上查询的输出如图所示,显示Student对象支配3个Vector对象。

如何理解java中MAT对OQL的支持

函数dominatorof()与dominators()的功能相反,它获取直接支配当前对象的对象。

SELECT distinct objects dominatorof(s) FROM jvm.chapter07.Student s

以上查询的输出如图所示,显示所有的Student对象直接被主线程支配。

如何理解java中MAT对OQL的支持

注意:函数dominatorof()与dominators()的功能正好相反。dominatorof()用于获得直接支配当前对象的对象,而dominators()用于获取直接支配对象。

下例取得引用WebPage的对象。

SELECT objects inbounds(w) FROM jvm.chapter07.WebPage w

下例取得堆快照中所有在jvm.chapter包中的存在对象实例的类型,其输出如图所示。

SELECT distinct objects classof(obj) FROM "jvm\.chapter07\..*" obj

如何理解java中MAT对OQL的支持


关于如何理解java中MAT对OQL的支持就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI