【发布时间】:2020-11-27 16:20:30
【问题描述】:
(defn sum [numbers]
(reduce + numbers))
(def numbers (into [] (range 0 100000000)))
(time (sum numbers))
上面是运行的代码。
只需将很多数字相加即可。
这行在repl中被执行了多次:(time (sum numbers))
每次它几乎都会让所有核心完全运行。
查看jvisualvm,创建的线程并不多。
但这段代码使用了我的 6 核笔记本电脑上可用的所有 12 个超线程。
幕后发生了什么使这成为可能?
【问题讨论】:
-
无关注释 -
(reduce + (range 0 100000000))明显更快,因为range返回一个知道如何在不创建中间序列的情况下减少自身的对象。(into [] ..)强制将整个范围实现为 1 个大序列。 -
你的 reduce 是单线程的。 Java 虚拟机可能正在处理垃圾收集或其他任务。 VisualVM 屏幕截图表明许多线程与 RMI 相关。
-
正如前面评论中提到的,有多种垃圾收集算法可供大多数 JVM 配置使用。其中一些将利用多个并行线程来执行垃圾收集工作。至少这似乎是您系统上正在发生的事情。当您启动不这样做的 JVM 时,您可以尝试手动选择 GC 算法,并查看它是否会改变使用的核心数。
-
这可能是因为使用 JMX 而死?甚至对于jvisualvm?见plumbr.io/handbook/gc-tuning-in-practice/other-examples/rmi-gc
标签: multithreading clojure jvm visualvm jvisualvm