在 Clojure 编程语言中,为什么这段代码表现出色?
(let [r (range 1e9)] [(first r) (last r)])
虽然这个失败了:
(let [r (range 1e9)] [(last r) (first r)])
我知道这是关于“失去理智”的建议,但你能向我解释一下吗?我还没来得及消化。
更新:
很难选出正确的答案,两个答案的信息量惊人。
注意:代码片段来自“The Joy of Clojure”。
最佳答案
详细说明dfan和 Rafał的答案,我花时间用 YourKit 运行这两个表达式分析器。
看到 JVM 的工作真是令人着迷。第一个程序对 GC 非常友好,以至于 JVM 在管理内存方面确实表现出色。
我画了一些图表。
GC 友好:(let [r (range 1e9)] [(first r) (last r)])
该程序运行时内存非常低;总体而言,不到6兆字节。如前所述,它对 GC 非常友好,它会进行大量回收,但只使用很少的 CPU。
头部固定器:(let [r (range 1e9)] [(last r) (first r)])
这个非常消耗内存。它的 RAM 高达 300 MB,但这还不够,程序无法完成(JVM 不到一分钟后就终止了)。 GC 占用了 90% 的 CPU 时间,这表明它拼命地尝试释放任何可以释放的内存,但找不到任何内存(收集到的对象很少甚至没有)。
编辑第二个程序内存不足,从而触发了堆转储。对此转储的分析表明,70% 的内存是 java.lang.Integer 对象,无法收集。这是另一个屏幕截图:
关于functional-programming - 惰性序列中 "Lose your head"的解释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5698122/