为什么这段代码不会抛出StackOverflow异常

zer*_*kms 6 jvm clojure

在clojure v1.6.0中,此代码只运行并占用一个核心的100%:

(defn average [x y] (/ (+ x y) 2))

(defn improve [guess x]
  (average guess (/ x guess)))

(defn sqrt-iter [guess x]
  (sqrt-iter (improve guess x) x))

(sqrt-iter 1 4)
Run Code Online (Sandbox Code Playgroud)

我希望它StackOverflowError立即抛出,但事实并非如此.

任何解释为什么会发生?

Die*_*sch 8

因为1很长.代码开始计算极长的有理数,并在几次迭代后慢慢爬行.如果你用1.0和4运行它,它会在几千次调用后非常快地吹掉堆栈(可能会因你的jvm参数而异).

  • 算术不长.它是一个比率,它在分母和分子中包含BigIntegers.BigIntegers将任意增长.请参阅https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Ratio.java (4认同)