VisualVM对OQL的支持
上上篇文章已经简单地介绍了如何通过VisualVM查看堆内存快照中的对象信息。但通常堆内存快照十分庞大,快照中的类数量也很多,很难通过浏览的方式找到所需的内容。为此,VisualVM提供了对OQL(对象查询语言)的支持,以方便开发人员在庞大的堆内存数据中快速定位所需的资源。
一,VisualVM的OQL基本语法
VisualVM的OQL是一种类似于SQL的查询语言。它的基本语法如下:
OQL由3个部分组成:select子句、from子句和where子句。select子句指定查询结果要显示的内容;from子句指定查询范围,可指定类名,如java.lang.String、char[]和Ljava.io.File(File数组);where子句指定查询条件。
select子句和where子句支持使用JavaScript语法处理较为复杂的查询逻辑,select子句可以使用类似JSON的语法输出多个列。from子句中可以使用instanceof关键字,将给定类的子类也包括到输出列表中。
在VisualVM的OQL中,可以直接访问对象的属性和部分方法。如下例中,直接使用了String对象的count属性,筛选出长度大于等于100的字符串。
如果要选取长度大于等于256的int数组,则语法如下:
如果要筛选出表示两位数的整数字符串,则语法如下:
上例中,select子句使用JSON语法,指定输出为String对象和String.toString();where子句使用正则表达式指定符合/^\d{2}$/条件的字符串。本例的部分输出数据如图6.59所示。
下例筛选出所有的文件路径及文件对象,其中调用了类的toString()方法。
下例使用instanceof关键字选取所有的ClassLoader,包括子类。
由于在Java程序中,一个Class类可能会被多个ClassLoader同时载入,因此在这种情况下可能需要使用Class的ID来指定Class。如下例,选出了所有ID为0x37A014D8的Class的对象实例。
注意:VisualVM的OQL语言支持JavaScript作为其子表达式。
二,内置heap对象
heap对象是VisualVMOQL的内置对象,通过heap对象可以实现一些强大的OQL功能。heap对象的主要方法如下:
·forEachClass():对每一个类对象执行一个回调操作。它的使用方法类似于heap.forEachClass(callback),其中callback为JavaScript函数。
·findClass():查找给定名称的类对象,返回类的方法和属性参考表6.3。它的调用方法类似于heap.findClass(className)。
·classes():返回堆快照中所有类的集合。使用方法类似于heap.classes()。
·objects():返回堆快照中所有的对象集合。使用方法类似于heap.objects(clazz,[includeSubtypes],[filter]),其中clazz指定类名称,includeSubtypes指定是否选出子类,filter为过滤器,指定筛选规则。includeSubtypes和filter可以省略。
·livepaths():返回指定对象的存活路径,即显示哪些对象直接或者间接引用了给定对象。它的使用方法类似于heap.livepaths(obj)。
·roots():返回这个堆的根对象。使用方法类似于heap.roots()。表6.3使用findClass()返回的Class对象拥有的属性和方法
例如,查找java.util.Vector类,语法如下:
查找java.util.Vector的所有父类,语法如下:
输出结果如下: