VisualVM OQL: найти объект, который имеет (косвенные) досягаемости/ссылки на два идентификатора объекта?

Мой вопрос довольно короткий и компактный:

Если я найду два объекта с помощью VisualVM, какой запрос OQL я могу выполнить, чтобы найти все объекты, которые имеют (косвенные) достижимые объекты или ссылки на эти два объекта?

Обновление для JB:

После редактирования вашего кода я пришел к следующему:

//QUERY SCRIPT: find object that (indirectly) references to all target objects
    //list all objects that the objects we search for should (indirectly) refer to
    var targetObjects =     [   heap.findObject("811819664"), //eg. obj that contains a player's health
                    heap.findObject("811820024") //eg. obj that contains the same player's name
                ];

    //list all objects here that every or most objects have as an indirect referer (eg. base class loaders)
    var ignoreReferers =    []; //eg. [heap.findObject("ignId1")];

    //set array with all elements that refer to each target object
    var targetObjectsReferers = [];
    for (var tarObjIndex in targetObjects) {
        var targetObjRefElements = [];

        //get the live path of this target object
        var livePaths = heap.livepaths(targetObjects[tarObjIndex]);

        //cleanup every live path
        for (var livePathsIndex in livePaths) {
            var curLivePath = livePaths[livePathsIndex];
            if ((curLivePath == null) || (curLivePath == "undefined")) continue;

            //remove last element from live path as it is the actual object
            curLivePath.pop();

            //remove elements that equal an ignore referer object
            for (var pathElementIndex in curLivePath) {
            if ((curLivePath[pathElementIndex] == null) || (curLivePath[pathElementIndex] == "undefined")) continue;

                for (var ignoreIndex in ignoreReferers) {
                    if (identical(curLivePath[pathElementIndex], ignoreReferers[ignoreIndex])) curLivePath.splice(pathElementIndex, 1); //FIXME: this might fail if index is not updated
                }
            }       
        }

        //merge remaining life paths elements into targetObjRefElements
        for (var livePathsIndex in livePaths) {
            var curLivePath = livePaths[livePathsIndex];

            for (var curLivePathIndex in curLivePath) {
                targetObjRefElements.push(curLivePath[curLivePathIndex]);
            }
        }

        //remove duplicate referers
        targetObjRefElements = unique(targetObjRefElements, 'objectid(it)');

        //add to target objects referers
        targetObjectsReferers.push(targetObjRefElements);
    }

    //filter and return
    filter(targetObjectsReferers[0], function(it1) {
        var rslt = contains(targetObjectsReferers[1], function(it2) { //FIXME: this limits it to 2 objects!
            return identical(it1, it2);
        });
        return rslt;
    });

Это возвращает поп-ошибку через некоторое время, которую я пытаюсь решить. Если мне удастся решить эту проблему, я увижу, дает ли она ожидаемые результаты.


person Tom    schedule 17.02.2011    source источник


Ответы (1)


Похоже, вы пытаетесь получить все цепочки ссылок, поддерживающие ваши объекты. Вы можете использовать функцию heap.livepaths(object) для их получения. Вы можете получить некоторые подсказки из следующего кода

var paths1 = heap.livepaths(heap.findObject("1684177040")) // use the objectid of the first instance
var paths2 = heap.livepaths(heap.findObject("1684177160")) // use the objectid of the second instance

var pathArr1 = unique(rcs2array(paths1), 'objectid(it)') // flatten all the livepaths to a single array of instances
var pathArr2 = unique(rcs2array(paths2), 'objectid(it)') // the same for the second instance

// calculate the arrays' intersection - the result is the set of object keeping both of your instances alive
filter(pathArr1, function(it1) { 
  var rslt = contains(pathArr2, function(it2) {
     return (objectid(it1) == objectid(it2))
  })
  return rslt
})

// helper function to convert an array of reference chains to a flat array of objects
function rcs2array(rcs) {
  var arr = new Array()

  for(var i=0;i<rcs.length;i++) {
    var rc = rcs[i];
    for(var j=0;j<rc.length;j++) {
        arr.push(rc[j])
    }
  }
  return arr
}

Пожалуйста, имейте в виду, что это работает только в VisualVM и jhat.

person JB-    schedule 18.02.2011
comment
Я пытался заставить что-то подобное работать. Как вы на самом деле выбираете результаты фильтра в VisualVM? Мне не кажется возможным добавить код вне оператора select? - person Tom; 18.02.2011
comment
Я обновил свой исходный вопрос кодом, который придумал. Может быть, ваш вариант имеет больше смысла, но разве вы не должны проверять каждый объект на наличие ссылок? И как вы выполняете код перед оператором select? - person Tom; 18.02.2011
comment
@ Tom 1. Вы можете полностью опустить выбор, если решите пойти по пути сложной логики JS. Если вы не используете форму select a from java.lang.Object a, механизм OQL принимает последний оператор скрипта в качестве желаемого результата. 2. Я не понимаю, что вы подразумеваете под проверкой каждого объекта на наличие ссылок. Можно поподробнее, пожалуйста? - person JB-; 18.02.2011
comment
Благодарю. Пожалуйста, проигнорируйте это утверждение, теперь я понимаю вашу логику (на самом деле моя не имела никакого смысла). Я снова обновил свой вопрос своей текущей версией (благодаря вашему ответу). У него есть некоторый недостаток, который я пытаюсь решить... буду обновлять, когда получу ожидаемые результаты или нет. - person Tom; 18.02.2011
comment
Могу я спросить вас, откуда вы узнали о синтаксисе OQL в jVisualVM? Мне не удалось найти исчерпывающую документацию (visualvm.java.net/oqlhelp.html довольно краткая ). Спасибо! - person Matthieu; 02.05.2017
comment
Собственно, я портировал jhat OQL на VisualVM. Итак, проверив исходный код. Справка OQL охватывает все стандартные части OQL, то, что вы можете видеть в этом примере, — это чистый JS, который использует вспомогательные функции для проверки содержимого дампа кучи. - person JB-; 09.05.2017