首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用oql进行java堆分析:计算唯一字符串

使用oql进行java堆分析:计算唯一字符串
EN

Stack Overflow用户
提问于 2011-11-23 20:28:52
回答 6查看 11.7K关注 0票数 16

我正在对现有的java软件进行内存分析。在oql中是否有一个sql 'group by‘等价物来查看具有相同值但不同实例的对象的计数。

select count(*) from java.lang.String s group by s.toString()

我想要获得重复字符串的列表以及重复字符串的数量。这样做的目的是查看具有大量数据的案例,以便可以使用String.intern()对其进行优化。

示例:

代码语言:javascript
复制
"foo"    100
"bar"    99
"lazy fox"    50

等等。

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2012-02-28 02:00:40

以下内容基于Peter Dolberg的回答,可以在VisualVM OQL控制台中使用:

代码语言:javascript
复制
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;
    }
   }
  );

它首先对所有String实例使用map()调用,并为每个String在counts数组中创建或更新一个对象。每个对象都有一个string和一个count字段。

生成的数组将为每个String实例包含一个条目,每个实例的count值都比相同字符串的前一个条目大1。然后在count字段上对结果进行排序,结果如下所示:

代码语言:javascript
复制
{
count = 1028.0,
string = *null*
}

{
count = 1027.0,
string = *null*
}

{
count = 1026.0,
string = *null*
}

...

(在我的测试中,字符串"*null*"是最常见的)。

最后一步是使用一个函数对此进行过滤,该函数在每个字符串第一次出现时返回true。它使用alreadyReturned数组来跟踪已经包含的字符串。

票数 23
EN

Stack Overflow用户

发布于 2012-02-24 14:43:13

我会使用Eclipse Memory Analyzer

票数 9
EN

Stack Overflow用户

发布于 2012-02-03 00:23:02

不幸的是,在OQL中没有"group by“的等价物。我假设你说的是jhat和VisualVM中使用的OQL。

不过,还有另一种选择。如果您使用纯JavaScript语法而不是"select x from y“语法,那么您可以使用JavaScript的全部功能。

尽管如此,获取您正在寻找的信息的另一种方法并不简单。例如,下面是一个OQL“查询”,它将执行与您的查询相同的任务:

代码语言:javascript
复制
var set={};
sum(map(heap.objects("java.lang.String"),function(heapString){
  if(set[heapString.toString()]){
    return 0;
  }
  else{
    set[heapString.toString()]=true;
    return 1;
  }
}));

在本例中,一个常规的JavaScript对象模拟一个集合(没有重复项的集合)。当map函数遍历每个字符串时,该集合用于确定是否已看到该字符串。重复项不计入总数(返回0),但新字符串计入(返回1)。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8242205

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档