河北网站建设电话,无为网站建设,品牌规划,酷炫的网站Visual VM对OQL的支持
上面我们学会了如何查看堆内存快照#xff0c;但是#xff0c;堆内存快照十分庞大#xff0c;快照中的类数量也很多。Visual VM提供了对OQL#xff08;对象查询语言#xff09;的支持#xff0c;以便于开发人员在庞大的堆内存数据中#xff0c;快…Visual VM对OQL的支持
上面我们学会了如何查看堆内存快照但是堆内存快照十分庞大快照中的类数量也很多。Visual VM提供了对OQL对象查询语言的支持以便于开发人员在庞大的堆内存数据中快速定位所需的资源。
2.1 Visual VM的OQL基本语法
OQL 语言是一种类似SQL的查询语言。基本语法如下 select JavaScript expression to select [ from [instanceof] class name identifier [ where JavaScript boolean expression to filter ] ]
OQL由3个部分组成select 子句、from 子句和where 子句。select 子句指定查询结果要显示的内容from 子句指定查询范围可指定类名如java.lang.String、char[]、[Ljava.io.FileFile数组;where 子句用于指定查询条件。
select 子句和where 子句支持使用Javascript 语法处理较为复杂的查询逻辑select 子句可以使用类似json的语法输出多个列from子句中可以使用instanceof关键字将给定类的子类也包括到输出列表中。
在Visual VM的OQL中可以直接访问对象的属性和部分方法。如下例中直接使用了String对象的count属性筛选出长度大于等于100的字符串
select s from java.lang.String s where s.count 100
选取长度大于等于256的 int 数组
select a from int[] a where a.length 256
筛选出表示两位数整数的字符串
select {instance: s, content: s.toString()} from java.lang.String s where /^\d{2}$/(s.toString())
上例中select 子句使用了json语法指定输出两列为String对象以及String.toString() 的输出。where 子句使用正则表达式指定了符合/^\d{2}$/条件的字符串。
下例使用 instance 关键字选取所有的ClassLoader包括子类
select cl from instanceof java.lang.ClassLoader cl;
由于在Java程序中一个类可能会被多个ClassLoader同时载入因此这种情况下可能需要使用Class的ID来指定Class。如下例选出了所有ID为0x37A014D8的Class对象实例。
select s from 0x37A014D8 s;
解决内存泄露的一个方法是分许heap dump文件可以参考 http://visualvm.java.net/oqlhelp.html
我自己总结了一下以后可能用到的一些OQL如下
查找所有包含指定类的list
heap.objects(heap.findClass(java.util.ArrayList),true, function(it){ if(it.size0){ return false ; } var i0; var data it.elementData[0]; var className classof(data).name; if(isClass(className)){ return true }else{ return false; } } )
function isClass(name){ var pattern /com.netease/ ; var result pattern.exec(name); return result!null; }
查找业务类直接或者间接引用的list
select filter(heap.livepaths(s),function(it){ var array it ; var i 0; var size array.length; for(;isize;i){ var className classof(array[i]).name; if(isClass(className)){ return true }else{ return false; } } return true ; }) from java.util.ArrayList s 查找包含内容最多的List这个应该是查找内存泄露的好语句 map(top(heap.objects(java.util.ArrayList), rhs.size - lhs.size, 5),toHtml(it)it.size)
查找当前系统属性 map(heap.objects(heap.findClass(com.netease.Main)),it.size)
查找同样内容最多的string var counts{}; var alreadyReturned{};
filter( sort( map(heap.objects(java.lang.String), function(heapString){ if( ! counts[heapString.toString()]){ counts[heapString.toString()] 1; } else { counts[heapString.toString()] counts[heapString.toString()] 1; } return { string:heapString.toString(), count:counts[heapString.toString()]}; }), lhs.count rhs.count), function(countObject) { if( ! alreadyReturned[countObject.string]){ alreadyReturned[countObject.string] true; return true; } else { return false; } } );