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

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

Если я найду два объекта в 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;
    });

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

1 Ответ

3 голосов
/ 18 февраля 2011

Звучит так, будто вы пытаетесь заставить все цепочки ссылок поддерживать ваши объекты живыми.Вы можете использовать функцию 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

...