使用oql进行java堆分析:计算唯一的字符串 [英] java heap analysis with oql: Count unique strings

查看:592
本文介绍了使用oql进行java堆分析:计算唯一的字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在对现有的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆