以后可能用到的一些OQL
Visual VM對(duì)OQL的支持
上面我們學(xué)會(huì)了如何查看堆內(nèi)存快照,但是,堆內(nèi)存快照十分龐大,快照中的類(lèi)數(shù)量也很多。Visual VM提供了對(duì)OQL(對(duì)象查詢(xún)語(yǔ)言)的支持,以便于開(kāi)發(fā)人員在龐大的堆內(nèi)存數(shù)據(jù)中,快速定位所需的資源。
2.1 Visual VM的OQL基本語(yǔ)法
OQL 語(yǔ)言是一種類(lèi)似SQL的查詢(xún)語(yǔ)言。基本語(yǔ)法如下:
select <JavaScript expression to select>
[ from [instanceof] <class name> <identifier>
[ where <JavaScript boolean expression to filter> ] ]
OQL由3個(gè)部分組成:select 子句、from 子句和where 子句。select 子句指定查詢(xún)結(jié)果要顯示的內(nèi)容;from 子句指定查詢(xún)范圍,可指定類(lèi)名,如java.lang.String、char[]、[Ljava.io.File(File數(shù)組);where 子句用于指定查詢(xún)條件。
select 子句和where 子句支持使用Javascript 語(yǔ)法處理較為復(fù)雜的查詢(xún)邏輯;select 子句可以使用類(lèi)似json的語(yǔ)法輸出多個(gè)列;from子句中可以使用instanceof關(guān)鍵字,將給定類(lèi)的子類(lèi)也包括到輸出列表中。
在Visual VM的OQL中,可以直接訪問(wèn)對(duì)象的屬性和部分方法。如下例中,直接使用了String對(duì)象的count屬性,篩選出長(zhǎng)度大于等于100的字符串:
select s from java.lang.String s where s.count >= 100選取長(zhǎng)度大于等于256的 int 數(shù)組:
select a from int[] a where a.length >= 256篩選出表示兩位數(shù)整數(shù)的字符串:
select {instance: s, content: s.toString()} from java.lang.String s where /^\d{2}$/(s.toString())上例中,select 子句使用了json語(yǔ)法,指定輸出兩列為String對(duì)象以及String.toString() 的輸出。where 子句使用正則表達(dá)式,指定了符合/^\d{2}$/條件的字符串。
下例使用 instance 關(guān)鍵字選取所有的ClassLoader,包括子類(lèi):
select cl from instanceof java.lang.ClassLoader cl;由于在Java程序中,一個(gè)類(lèi)可能會(huì)被多個(gè)ClassLoader同時(shí)載入,因此,這種情況下,可能需要使用Class的ID來(lái)指定Class。如下例,選出了所有ID為0x37A014D8的Class對(duì)象實(shí)例。
select s from 0x37A014D8 s;解決內(nèi)存泄露的一個(gè)方法是分許heap dump文件,可以參考?http://visualvm.java.net/oqlhelp.html
我自己總結(jié)了一下以后可能用到的一些OQL,如下:
查找所有包含指定類(lèi)的list
heap.objects(heap.findClass("java.util.ArrayList"),true, function(it){
 if(it.size<=0){
 return false ;
 }
 var i=0;
 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;
 }
查找業(yè)務(wù)類(lèi)直接或者間接引用的list
select filter(heap.livepaths(s),function(it){
 var array = it ;
 var i= 0;
 var size = array.length;
 for(;i<size;i++){
 var className = classof(array[i]).name;
 if(isClass(className)){
 return true
 }else{
 return false;
 }
 }
 return true ;
 })?
 from java.util.ArrayList s
?
查找包含內(nèi)容最多的List,這個(gè)應(yīng)該是查找內(nèi)存泄露的好語(yǔ)句
 map(top(heap.objects('java.util.ArrayList'), 'rhs.size - lhs.size', 5),"toHtml(it)+'='+it.size")
查找當(dāng)前系統(tǒng)屬性
 map(heap.objects(heap.findClass("com.netease.Main")),"it.size")
查找同樣內(nèi)容最多的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;
 }
 }
 );
?
總結(jié)
以上是生活随笔為你收集整理的以后可能用到的一些OQL的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
 
                            
                        - 上一篇: 一般拦截器 serviceImpl部分
- 下一篇: 一个拆分使用的存储过程例子
