1

考虑以下代码。这段代码几乎实现了 Chicken Scheme 风格的递归,其中大部分时间函数是直接调用的,但偶尔会有更复杂的蹦床过程。但是,代码不能完全正常工作。我真正想要的是一个方法 stackLimitsAlmostReached,它返回一个布尔值,指示是否存在堆栈溢出的危险。如何检查堆栈限制,并在 Java 中完成 Chicken Scheme 风格的递归?

import java.util.Scanner;

public class Main {

public static abstract class Thunk {
    public abstract Thunk x();

    public final void run() {
        Thunk ip = this;

        while (ip != null)
            ip = ip.x();
    }
}

public static void main(String[] unused) {
    final Scanner scanner = new Scanner(System.in);

    new Thunk() {
        public Thunk x() {
            System.out.println("Hello World!");

            try {
                return this.x();
            } catch (StackOverflowError t) {
                System.out.println("GC!");
                scanner.nextLine();
                return this;
            }
        }
    }.run();
}
}
4

1 回答 1

1

嘿,我可能误解了你的问题,但我认为你必须首先寻找这些选项(Java 明智,但这不是 IMO 的问题)

-ss Stacksize to increase the native stack size or

-oss Stacksize to increase the Java stack size,

The default native stack size is 128k, with a minimum value of 1000 bytes. The default java stack size is 400k, with a minimum value of 1000 bytes.

But what i really feel i should warn you about is that the JVM can't support tail call optimisation because of it's security model. Wikipedia . Each time you call the same function , you introduce a new stack frame and that's why you run on limits fast. A proper scheme that supports TCO doesn't actually create a new stack frame , it just updates the values and returns to a continuation at the start of the current frame. this makes recursion very efficient.

Even clojure that runs on the JVM suffers from this problem , that's why it has a lambda called recur to handle that limitation. check also : TCO paper

于 2012-09-15T00:53:06.327 回答