【问题标题】:VisualVM OQL: find object that has (indirect) reachables/references to two object IDs?VisualVM OQL:找到具有(间接)可达性/引用两个对象 ID 的对象?
【发布时间】:2011-02-17 21:07:34
【问题描述】:

我的问题相当简短:

如果我使用 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 is not defined 错误,我正在尝试解决这个错误。如果我设法解决,我可以看看它是否提供了预期的结果。

【问题讨论】:

    标签: java visualvm oql


    【解决方案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

    【讨论】:

    • 我一直试图让类似的工作。您如何在visualVM中实际选择过滤器的结果?我似乎无法在 select 语句之外添加代码?
    • 我已经用我想出的代码更新了我原来的问题。也许你的更有意义,但你不应该检查每个对象的引用吗?以及如何在 select 语句之前执行代码?
    • @Tom 1. 如果你决定走复杂的 JS 逻辑,你可以完全省略 select。如果您不使用“从 java.lang.Object a 中选择 a”形式,OQL 引擎会将最后一个脚本语句作为所需结果。 2.我不明白您所说的“检查每个对象的引用”是什么意思。请详细说明一下好吗?
    • 谢谢。请忽略该声明,我现在理解您的逻辑(我的逻辑实际上根本没有任何意义)。我用当前版本再次更新了我的问题(感谢您的回答)。它有一些我正在尝试解决的缺陷。当我得到预期的结果时会更新。
    • 实际上,我将 jhat OQL 移植到了 VisualVM。因此,通过检查源代码。 OQL 帮助涵盖了 OQL 的所有标准部分,您可以在此示例中看到纯 JS,它使用辅助函数检查堆转储内容。
    猜你喜欢
    • 1970-01-01
    • 2019-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多