解释 VisualVM 回溯

Interpreting a VisualVM backtrace

我正在对我的 Mandelbrot 集合浏览器进行 CPU 分析。出于某种原因,java.lang.PersistentHashMap$BitmapIndexedNode.find 使用了相当大比例的总 CPU 时间。当我拍摄分析结果的快照并获得该方法的回溯时,我得到:

我看到很多关于 BigDecimal 操作的引用。似乎 BigDecimal 运算符在某些时候需要在 PersistentHashMap.

上调用 find

我对回溯的解释正确吗?对 find 的调用是否是 BigDecimal 操作的结果,这意味着我对此无能为力?对他们来说,这似乎是一件奇怪的事情。尽管要验证这一点,但我很难比 clojure.lang.Numbers$BigDecimalOps 更深入地挖掘。

你的解释是正确的。加法、乘法、否定、除法和其他 BigDecimal 运算最终会进行哈希映射查找。这些是取消引用 *math-context* Var 的一部分。每次在 Clojure 中对两个 BigDecimal 对象执行算术运算时都会发生这种情况。除了切换到其他数字类型,如 double.

之外,没有什么可以做的。

clojure.core/*math-context* 动态 Var 没有文档字符串。据我所知,它旨在容纳 java.math.MathContext object. MathContext objects can be used to specify precision and rounding mode for BigDecimal operations. If *math-context* is bound, its value is passed to BigDecimal methods in the Java runtime as in BigDecimal.add(BigDecimal augend, MathContext mc). When *math-context* is not bound, BigDecimal methods are called 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
  • getThreadBinding
  • 中的哈希映射 is looked up