代码之家  ›  专栏  ›  技术社区  ›  Scruffers

oql查询,查找会话中引用的给定类的所有实例和子实例

  •  4
  • Scruffers  · 技术社区  · 16 年前

    我尝试使用jhat/oql来跟踪Tomcat容器中的内存泄漏。我想问的问题是:

    “显示可从javax.servlet.http.httpsession访问的foo.bar.cacheable类的所有实例(和子实例)”

    我设法想出了以下方法,但这并不显示 可缓存foo.bar. (这很重要,因为这会影响到接口)。

    select filter(reachables(s), "/foo.bar.Cacheable/(classof(it).name)") from javax.servlet.http.HttpSession s
    

    我尝试了以下概念的各种排列,但只是不断出错(“foo”没有定义)。

    select filter(reachables(s), classof(it) instanceof foo.bar.Cacheable) from javax.servlet.http.HttpSession s
    

    有人能帮我解决我做错了什么通过OQL提出这个问题吗?

    1 回复  |  直到 9 年前
        1
  •  3
  •   JB-    15 年前

    在基于JHAT的OQL实现(JHAT,VisualVM)中,您可以利用这样一个事实:您不仅限于类似SQL的语法,而且手头上有一个完整的JavaScript引擎。

    下面这段代码就可以了

    var containerSuperClass = "javax.servlet.http.HttpSession"
    var elementSuperClass = "foo.bar.Cacheable"
    // find the container class by name
    var alClz = heap.findClass(elementSuperClass)
    // retrieve all subclasses
    var subClzs = alClz.subclasses()
    
    // filter the list of objects reachables from instances of the container super class
    // and all its subclasses so it contains only objects of classes from subClzs
    map(heap.objects(containerSuperClass), 'filter(reachables(it), "it != null && contains(subClzs, containsClause(it))")')
    
    // we need to externalize the contains clause because of clash in naming the closure parameter 'it'
    function containsClause(rcbl) {
        return function(it) {
            if (rcbl == null || it == null) return false;
            return it.name.equals(classof(rcbl).name)
        }
    }