Multithreading clojure reduce函数使用所有内核,即使它看起来是单线程的

Multithreading clojure reduce函数使用所有内核,即使它看起来是单线程的,multithreading,clojure,jvm,visualvm,jvisualvm,Multithreading,Clojure,Jvm,Visualvm,Jvisualvm,上面是运行的代码 简单地把很多数字加起来 这一行在repl中执行了多次: (时间(总数)) 每次它几乎让所有内核都完全运行 查看jvisualvm,创建的线程并不多 但这段代码使用了我的6核笔记本电脑上的所有12个超线程 幕后发生了什么使这成为可能?多亏了这些评论 这与射程的大小有关 在我的笔记本电脑上,当它有大约7000万个数字时,一切都很好 当它达到8000万左右时,堆的大小会大大增加,所花费的时间也会显著增加,所有的内核都开始工作。可视化虚拟机显示更多的GC活动正在发生 因此,上面的评论

上面是运行的代码

简单地把很多数字加起来

这一行在repl中执行了多次:
(时间(总数))
每次它几乎让所有内核都完全运行

查看jvisualvm,创建的线程并不多

但这段代码使用了我的6核笔记本电脑上的所有12个超线程


幕后发生了什么使这成为可能?

多亏了这些评论

这与射程的大小有关

在我的笔记本电脑上,当它有大约7000万个数字时,一切都很好

当它达到8000万左右时,堆的大小会大大增加,所花费的时间也会显著增加,所有的内核都开始工作。可视化虚拟机显示更多的GC活动正在发生


因此,上面的评论可能是对的,它与GC有关。

不相关的注释-
(reduce+(range 0 100000000))
的速度要快得多,因为
range
返回的对象知道如何在不创建中间序列的情况下减少自身<代码>(进入[]…)强制将整个范围实现为一个大序列。您的reduce是单线程的。Java虚拟机可能正在处理垃圾收集或其他任务。VisualVM屏幕截图表明,许多线程与RMI相关。正如前面的评论中提到的,大多数JVM都可以配置使用多种垃圾收集算法。其中一些将利用多个并行线程来执行垃圾收集工作。这似乎至少有可能发生在你的系统上。您可以尝试在启动不执行此操作的JVM时手动选择GC算法,并查看它是否会更改使用的内核数?甚至对于jvisualvm?看见
(defn sum [numbers]
  (reduce + numbers))

(def numbers (into [] (range 0 100000000)))

(time (sum numbers))