OQL查询以查找从会话引用的给定类的所有实例和子实例

时间:2010-04-22 16:42:30

标签: java memory-leaks heap jhat oql

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

“显示foo.bar.Cacheable类的所有实例(和子实例),可以从javax.servlet.http.HttpSession”

访问

我设法提出以下内容,但这并未显示 foo.bar.Cacheable 的子类(这很重要,因为这实际上是一个接口)。

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 个答案:

答案 0 :(得分:4)

在基于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)
    }
}