解释 VisualVM 回溯
Posted
技术标签:
【中文标题】解释 VisualVM 回溯【英文标题】:Interpreting a VisualVM backtrace 【发布时间】:2017-07-17 16:52:59 【问题描述】:我正在 Mandelbrot Set 浏览器上进行 CPU 分析。出于某种原因,java.lang.PersistentHashMap$BitmapIndexedNode.find
使用了相当大比例的总 CPU 时间。当我对分析结果进行快照并获得方法的回溯时,我得到了:
我看到很多对BigDecimal
操作的引用。似乎BigDecimal
运营商在某些时候需要在PersistentHashMap
上调用find
。
我对回溯的解释正确吗?对find
的调用是BigDecimal
操作的结果,这意味着我对此无能为力吗?这对他们来说似乎是一件奇怪的事情。不过,我很难比clojure.lang.Numbers$BigDecimalOps
更深入地挖掘来验证这一点。
【问题讨论】:
【参考方案1】:你的解释是正确的。加法、乘法、否定、除法和其他BigDecimal
操作最终会进行哈希映射查找。这些是取消引用*math-context*
Var 的一部分。每次在 Clojure 中对两个 BigDecimal
对象执行算术运算时都会发生这种情况。除了切换到其他数字类型(例如double
)之外,没有什么可以做的。
clojure.core/*math-context*
动态变量没有文档字符串。据我所知,它旨在保存一个java.math.MathContext 对象。 MathContext 对象可用于为 BigDecimal 操作指定精度和 rounding mode。如果绑定了*math-context*
,则其值将传递给Java 运行时中的BigDecimal 方法,就像BigDecimal.add(BigDecimal augend, MathContext mc) 中一样。当*math-context*
未绑定时,BigDecimal 方法称为without passing a context。
问题中堆栈跟踪的相关部分是:
...
clojure.lang.PersistentHashMap.entryAt(Object)
clojure.lang.Var.getThreadBinding()
clojure.lang.Var.deref()
clojure.lang.Numbers$BigDecimalOps.add/multiply/..
...
一些指向 Clojure 源代码的指针:
*math-context*
变量defined
*math-context*
在执行 BigDecimal addition 时取消引用。其他操作也会发生同样的情况
取消引用 Var 需要调用 getThreadBinding
is looked up 内的哈希映射 getThreadBinding
【讨论】:
以上是关于解释 VisualVM 回溯的主要内容,如果未能解决你的问题,请参考以下文章
如何解释 visualvm cpu 示例和从中创建的快照之间的不一致?