2011-02-17 1 views
0

Мой вопрос довольно короткий и компактный: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; 
    }); 

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

ответ

3

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

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

+0

Я пытался получить что-то подобное работу. Как вы фактически выбираете результаты фильтра в visualVM? Мне кажется, не представляется возможным добавить код вне выражения select? – Tom

+0

Я обновил свой оригинальный вопрос кодом, который я придумал. Может быть, ваш смысл имеет смысл, но разве вы не должны проверять каждый объект для ссылок? И как вы выполняете код для команды select? – Tom

+0

@Tom 1. Вы можете полностью отказаться от выбора, если решите пойти по пути сложной логики JS. Если вы не используете форму «выбрать a из java.lang.Object a», то механизм OQL принимает последний оператор сценария как желаемый результат. 2. Я не понимаю, что вы подразумеваете под «проверять каждый объект для ссылок». Можете ли вы уточнить, пожалуйста? –