анализ кучи java с oql: подсчет уникальных строк

Im делает анализ памяти существующего программного обеспечения java. Есть ли эквивалент sql "group by" в oql, чтобы увидеть количество объектов с одинаковыми значениями, но разными экземплярами.

выберите количество(*) с явы.ленг.Строку s группа С. метод toString()

Я хотел бы получить список дублированных строк вместе с количеством дубликатов. Цель этого-увидеть случаи с большими числами, чтобы их можно было оптимизировать с помощью Строка.интерн.)(

пример:

"foo"    100
"bar"    99
"lazy fox"    50

etc...

5 ответов


ниже в зависимости от ответа Петр Дольберг и может быть использовано в , который 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;
    }
   }
  );

он начинается с использования map() вызовите все экземпляры String и для каждой строки создайте или обновите объект в counts массив. Каждый объект имеет string и


Я хотел бы использовать Анализатор Памяти Eclipse вместо.


к сожалению, в OQL нет эквивалента "group by". Я предполагаю, что вы говорите о OQL, который используется в jhat и VisualVM.

однако есть альтернатива. Если вы используете чистый синтаксис JavaScript вместо синтаксиса" выбрать x из y", то у вас есть полная мощность JavaScript для работы.

тем не менее, альтернативный способ получения информации, которую вы ищете, не прост. Например, вот "запрос" OQL, который будет выполнять ту же задачу, что и ваш запрос:

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).


гораздо более эффективный запрос:

var countByValue = {};

// Scroll the strings
heap.forEachObject(
  function(strObject) {
    var key = strObject.toString();
    var count = countByValue[key];
    countByValue[key] = count ? count + 1 : 1;
  },
  "java.lang.String",
  false
);

// Transform the map into array
var mapEntries = [];
for (var i = 0, keys = Object.keys(countByValue), total = keys.length; i < total; i++) {
  mapEntries.push({
    count : countByValue[keys[i]],
    string : keys[i]
  });
}

// Sort the counts
sort(mapEntries, 'rhs.count - lhs.count');

просто опубликуйте мое решение и опыт при выполнении аналогичной проблемы для других ссылок.

var counts = {};
var alreadyReturned = {};
top(
filter(
    sort(
        map(heap.objects("java.lang.ref.Finalizer"),
            function (fobject) {
                var className = classof(fobject.referent)
                if (!counts[className]) {
                    counts[className] = 1;
                } else {
                    counts[className] = counts[className] + 1;
                }
                return {string: className, count: counts[className]};
            }),
        'rhs.count-lhs.count'),
    function (countObject) {
        if (!alreadyReturned[countObject.string]) {
            alreadyReturned[countObject.string] = true;
            return true;
        } else {
            return false;
        }
    }),
    "rhs.count > lhs.count", 10);

предыдущий код выведет 10 лучших классов, используемых java.ленг.ссылка.Метод завершения.
Советы:
1. Функция сортировки с помощью функции XXX не работает в моей Mac OS.
2. Функция classof может возвращать класс референта. (Я попытался использовать fobject.референт.toString () - > это вернуло много org.среда NetBeans.движение за освобождение.профилировщик.куча.InstanceDump. Это также зря потратил много времени).