分析堆转储,Map#size()不是函数?

时间:2012-11-08 19:03:55

标签: java heap visualvm oql

得到这个奇怪的错误:

javax.script.ScriptException: sun.org.mozilla.javascript.internal.EcmaError: TypeError: size is not a function, it is null. (#1)

分析堆转储并在VisualVM上运行此OQL查询时:

select { map: x } 
from java.util.concurrent.ConcurrentHashMap x 
where x.size() < 10

问题出在where子句上,虽然Map显然有一个大小方法,但它不起作用。

2 个答案:

答案 0 :(得分:3)

除了一件小事之外,@ ruakh的回答非常好。段有时可能为空,这会混淆sum(x.segments, 'it.count')。替换为

sum(x.segments, 'it != null ? it.count : 0')

它会正常工作。测试了我的话。

答案 1 :(得分:2)

通过the VisualVM OQL documentation,我不会觉得它支持Java方法调用,只支持Java字段。 (他们的一些示例包括.toString(),但这显然是JavaScript .toString()而不是Java {1},因为它们使用它将Java String对象转换为JavaScript字符串。)所以,例如,它们的字符串长度示例都使用私有字段count而不是公共方法length(),并且它们的矢量长度示例使用私有字段{{1而不是公共方法elementCount

所以你得到的错误是因为size()没有名为ConcurrentHashMap的字段。

不幸的是,对于您的查询,size不会将其大小存储在字段中 - 这会影响其避免阻止的能力 - 因此我认为您必须编写类似这样的内容:

ConcurrentHashMap

自己对所有细分大小求和。 (免责声明:100%完全未经测试。)