2015-02-26 8 views
4

У меня есть куча дампов из приложения и выяснено, что в нем огромное количество ArrayLists с одним объектом. Я знаю, как получить список таких ArrayLists, а также показать класс содержащегося элемента:Получите количество объектов, на которые ссылается ArrayList с размером 1, сгруппированным по классу

SELECT list.elementData[0] FROM java.util.ArrayList list WHERE (list.size = 1) 

Результат выглядит следующим образом:

java.lang.String [id=0x7f8e44970] 
java.lang.String [id=0x7f8e44980] 
java.lang.String [id=0x7f8e44572] 
java.io.File [id=0x7f8e43572] 
... 

То, что я хотел бы, чтобы получить что-то вроде этого :

Class    | count 
================================= 
java.lang.String | 100 
java.io.File  | 74 
... 

, но я не могу агрегировать результаты или делать что-либо еще на них. Я нашел here, как передать значения во внешний выбор, но я не могу понять, как использовать что-либо еще рядом с * в первом выборе.

SELECT * from OBJECTS 
(SELECT OBJECTS list.elementData[0] FROM java.util.ArrayList list WHERE (list.size = 1)) 

ответ

2

Там нет в VisualVM's OQL нет group by Но вы можете использовать встроенные функции, чтобы сделать сниппет JavaScript и запустить его в «OQL консоли»:

var c = {}; 

/* Filter to show only the first occurence (max count) */ 
filter(
    /* Sort by occurences desc */ 
    sort(
    /* Count class instances */ 
    map(
     heap.objects("java.util.ArrayList"), 
     function(list) { 
     var clazz = 'null'; 
     if (list.size = 1 && list.elementData[0] != null) { 
      clazz = classof(list.elementData[0]).name; 
     } 

     c[clazz] = (c[clazz] ? c[clazz] + 1 : 1); 
     return { cnt:c[clazz], type:clazz }; 
     } 
    ), 'rhs.cnt - lhs.cnt' 
), 
    function (item) { 
    if (c[item.type]) { 
     c[item.type] = false; 
     return true; 
    } else { 
     return false; 
    } 
    } 
); 

Выход представляет собой массив объект как:

{ 
cnt = 3854.0, 
type = null 
}  
{ 
cnt = 501.0, 
type = org.apache.tomcat.util.digester.CallMethodRule 
} 
{ 
cnt = 256.0, 
type = java.lang.ref.WeakReference 
} 
{ 
cnt = 176.0, 
type = sun.reflect.generics.tree.SimpleClassTypeSignature 
} 

Наконец, вы можете вызвать функцию map снова для форматирования вывода на что-то другое, как на exmpale как CSV:

map( 
    filter(...), 
    'it.type + ", " + it.cnt' 
); 

выход:

null, 3854  
org.apache.tomcat.util.digester.CallMethodRule, 501  
java.lang.ref.WeakReference, 256  
sun.reflect.generics.tree.SimpleClassTypeSignature, 176  
org.apache.tomcat.util.digester.CallParamRule, 144  
com.sun.tools.javac.file.ZipFileIndex$Entry, 141  
org.apache.tomcat.util.digester.ObjectCreateRule, 78 
+0

Спасибо! Это работает. – NeplatnyUdaj