我的问题相当简短和紧凑:
如果我在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;
});
这会在一段时间后返回一个pop定义错误,我试图解决。如果我设法解决这个问题,我可以看看它是否能提供预期结果。
答案 0 :(得分:3)
听起来你正试图让所有参考链保持你的物体存活。您可以使用 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