OQL в VisualVM - рекурсивная печать данных stati c из пакета - PullRequest
1 голос
/ 11 февраля 2020

Я хотел бы построить запрос OQL , с помощью которого можно рекурсивно распечатать все stati c данных дампа кучи JVM из классов в пределах указанного c пакет. Я знаю, что существует много проблем при рекурсивном обращении к памяти, но (по крайней мере, на начальном этапе) я уменьшу их, установив порог глубины.

Согласно документации, классы имеют statics поле, которое в свою очередь должно состоять из name s и value s:

statics - имя, пары значений для полей stati c класса .

Я остановился в получении имени каждого из этих полей c с помощью выражения field.name и не знаю, как выполнить итерацию объекта в другом состоянии. c полей. В настоящее время у меня есть:

select map(
    filter(
        filter(heap.classes(), "/com.heap./.test(it.name)"),
        function (clazz) {
            if (clazz.statics) {
                return true;
            }
            return false;
        }
    ), function (clazz) {
        var res = '';
        res += toHtml(clazz.name) + " : " + toHtml(clazz.statics) + "<br>";
        map(clazz.statics, function (field) {
            res += "--" + toHtml(field) + "," + toHtml(field.name) + "," + toHtml(field.state) +"<br>";
        });
        return res + "<br>";
    }
)

и получить следующий вывод:

com.heap.dump.DataHolder : { :sun.misc.Launcher$AppClassLoader#1, }
--sun.misc.Launcher$AppClassLoader#1,null,null

com.heap.dump.HeapDumperTest : { dataHolder:com.heap.dump.DataHolder#1, mutableStaticState:java.lang.String#225, :sun.misc.Launcher$AppClassLoader#1, }
--com.heap.dump.DataHolder#1,null,java.lang.String#224
--java.lang.String#225,null,null
--sun.misc.Launcher$AppClassLoader#1,null,null

com.heap.dump.Main : { :sun.misc.Launcher$AppClassLoader#1, }
--sun.misc.Launcher$AppClassLoader#1,null,null

Я перебираю clazz.statics, используя функцию map(), следуя этому ответу .

Похоже, что аргумент field является просто значением поля, поскольку field.name всегда null и field.state фактически извлекает поле одного из объектов (com.heap.dump.DataHolder.state) .

Основные вопросы:

  • Итерируя поля stati c, как можно получить имя поля, кроме значения?
  • Как только я получу объект / экземпляр, который я хочу пройти, как мне перебрать нестатические c поля (имя и значение) для этого объекта? Этот способ получения значения поля, как и оператор field.state, выглядит полезным, только если я уже знаю имена полей, что здесь не так.

Дополнительные вопросы:

  • Как отфильтровать пустые поля AppClassLoader stati c?
  • Использую ли я не тот инструмент для работы? Есть ли более простая альтернатива OQL в VisualVM?

1 Ответ

1 голос
/ 12 февраля 2020

statics - карта, поэтому вы должны использовать for(..) для ее итерации. Я обновил ваш запрос. Смотрите ниже:

select map(
    filter(
        filter(heap.classes(), "/com.heap./.test(it.name)"),
        function (clazz) {
            if (clazz.statics) {
                return true;
            }
            return false;
        }
    ), function (clazz) {
        var res = '';
        res += toHtml(clazz.name) + " :<br>";
        for (field in clazz.statics) {
            res += "-- " + toHtml(field) + ", " + toHtml(clazz.statics[field]) +"<br>";
        }
        return res + "<br>";
    }
)
...