Java程序员性能优化实战必看:MAT对OQL的支持

Java程序员性能优化实战必看:MAT对OQL的支持,第1张

Java程序员性能优化实战必看:MAT对OQL的支持 MAT对OQL的支持

前置文章:发布即巅峰!万字长文:Java性能调优六大工具:MAT内存分析工具

MAT的OQL语法与VisualVM支持的OQL有很大的区别。因此,笔者分为单独的两节分别对这两种OQL语言进行阐述。与VisualVM的OQL不同,MAT的OQL在语法上更接近传统的SQL语句。

一,Select子句

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

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

与VisualVM的OQL类似,在OQL中,可以直接访问对象的属性。

下例输出所有Vector对象的内部数组,输出结果如图6.101所示。

下例将显示String对象的长度及内部数组。

MAT还支持自定义列名,下例便使用ASColName的形式自定义表格列名,结果如图6.102所示。

在Select子句中,使用ASRETAINEDSET关键字可以得到指定对象的保留集。下例得到
javatuning.ch6.toolscheck.shallowretained.Line对象的保留集,其结果如图6.103所示(堆快照文件为6.7.2节“浅堆和深堆”中的示例)。

在Select子句中,使用OBJECTS关键字可以将返回结果集中的项以对象的形式显示,例如下例的输出结果如图6.104所示。与图6.101相比,返回的结果已经被解析成完整的对象,而非简单的对象描述信息。

注意:在Select子句中使用OBJECTS关键字,可以将结果集解析为对象。

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

二,From子句

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

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

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

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

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

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

在From子句中,还可以使用OBJECTS关键字,此时原本应该返回类的实例的查询,将返回类的信息。在笔者完稿前,该功能尚处于测试阶段。例如:

以上查询的返回结果如图6.108所示。它仅返回一条记录,表示java.lang.String的类的信息。如果不使用OBJECTS关键字,这个查询将返回所有的java.lang.String实例。

OBJECTS关键字也支持与正则表达式一起使用。下面的查询返回了所有满足给定正则表达式的类,其结果如图6.109所示。读者可以与图6.106比较异同。

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

三,Where子句

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

下例返回长度大于100的字符串对象。

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

下例返回所有value域不为null的字符串,使用了等于 *** 作符。

Where子句支持多个条件的AND、OR运算。下例返回偏移量大于0并且长度大于10的所有字符串。

下例返回长度大于100或者内部value域长度大于100的字符串。

四,内置对象与方法

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

其中alias为对象名称。例如下例将访问String对象的count属性。

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

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

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

其中alias为对象名称,attribute为属性名。下例将显示String对象中value数组的长度。

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

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

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

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

下例将显示长度大于100的字符串内部char数组value中,索引为2的字符。

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

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

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

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

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

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

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

下例将显示所有长度为15的字符串内容。

下例将显示所有
javatuning.ch6.toolscheck.shallowretained.Line对象的直接支配对象,即给定对象回收后将释放的对象集合。

以上查询的输出结果如图6.111所示,显示Line对象支配了4个Point对象。

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

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

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

下例将取得引用Line的对象。

下例将取得堆快照中所有在javatuning.ch6包中的对象类型,输出结果如图6.113所示。

本文给大家讲解的内容是MAT对OQL的支持
  1. 下篇文章给大家讲解的内容是来自JRockit的礼物——JMC
  2. 觉得文章不错的朋友可以转发此文关注小编;
  3. 感谢大家的支持!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5612515.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-15
下一篇 2022-12-15

发表评论

登录后才能评论

评论列表(0条)

保存