使用oql进行java堆分析:计算唯一的字符串 [英] java heap analysis with oql: Count unique strings
问题描述
我正在对现有的java软件进行内存分析。在oql中是否有一个sql'group by'等价来查看具有相同值但实例不同的对象的数量。
Im doing a memory analysis of an existing java software. Is there a sql 'group by' equivalent in oql to see the count of objects with same values but different instances.
从java中选择count(*)
.lang.String s
group by s.toString()
select count(*) from java.lang.String s group by s.toString()
我想获得重复字符串的列表以及重复的数量。这样做的目的是查看具有大数字的案例,以便可以使用String.intern()优化它们。
I'd like to achieve a list of duplicated strings along with the number of duplicates. The purpose of this is to see the cases with large numbers so that they could be optimized using String.intern().
示例:
"foo" 100
"bar" 99
"lazy fox" 50
等...
推荐答案
以下是基于Peter Dolberg的答案,可用于 VisualVM OQL控制台:
The following is based on the answer by Peter Dolberg and can be used in the VisualVM OQL Console:
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;
}
}
);
首先使用 map()
调用所有String实例,并为每个String创建或更新 counts
数组中的对象。每个对象都有一个字符串
和一个 count
字段。
It starts by using a map()
call over all String instances and for each String creating or updating an object in the counts
array. Each object has a string
and a count
field.
结果数组将包含每个String实例的一个条目,每个条目的 count
值比同一个String的前一个条目大一个。
结果然后在 count
字段中排序,结果如下所示:
The resulting array will contain one entry for each String instance, each having a count
value one larger than the previous entry for the same String.
The result is then sorted on the count
field and the result looks something like this:
{
count = 1028.0,
string = *null*
}
{
count = 1027.0,
string = *null*
}
{
count = 1026.0,
string = *null*
}
...
(在我的测试中,String * null *
是最常见的。)
(in my test the String "*null*"
was the most common).
最后一步是使用一个函数对其进行过滤,该函数对于每个String的第一次出现都返回true。它使用 alreadyReturned
数组来跟踪已包含的字符串。
The last step is to filter this using a function that returns true for the first occurrence of each String. It uses the alreadyReturned
array to keep track of which Strings have already been included.
这篇关于使用oql进行java堆分析:计算唯一的字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!