paw*_*que 14 java memory heap performance
我正在对现有的java软件进行内存分析.在oql中是否有一个sql'group by'等价来查看具有相同值但不同实例的对象的数量.
通过s.toString()从java.lang.String s group中选择count(*)
我想要获得重复字符串的列表以及重复的数量.这样做的目的是查看大数字的情况,以便可以使用String.intern()优化它们.
例:
"foo" 100
"bar" 99
"lazy fox" 50
Run Code Online (Sandbox Code Playgroud)
等等...
Joh*_*ing 22
以下是基于Peter Dolberg的答案,可以在VisualVM OQL控制台中使用:
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;
}
}
);
Run Code Online (Sandbox Code Playgroud)
它首先使用map()对所有String实例的调用以及为每个String创建或更新counts数组中的对象.每个对象都有一个string和一个count字段.
结果数组将为每个String实例包含一个条目,每个条目的count值都大于同一String的前一个条目.然后在count字段上对结果进行排序,结果如下所示:
{
count = 1028.0,
string = *null*
}
{
count = 1027.0,
string = *null*
}
{
count = 1026.0,
string = *null*
}
...
Run Code Online (Sandbox Code Playgroud)
(在我的测试中,String "*null*"是最常见的).
最后一步是使用一个函数对其进行过滤,该函数在每个String的第一次出现时返回true.它使用alreadyReturned数组来跟踪已包含的字符串.