1

次のコードを検討してください。このコードは、ほとんどの場合関数が直接呼び出されるチキンスキームスタイルの再帰をほぼ実装していますが、より複雑なトランポリン手順が存在する場合もあります。ただし、コードは正しく機能しません。私が本当に必要としているのは、スタックオーバーフローの危険性があるかどうかを示すブール値を返すメソッド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,

デフォルトのネイティブ スタック サイズは 128k で、最小値は 1000 バイトです。デフォルトの Java スタック サイズは 400k で、最小値は 1000 バイトです。

しかし、私が警告すべきだと本当に感じているのは、JVM はセキュリティ モデルであるため、テール コールの最適化をサポートできないということです。ウィキペディア。同じ関数を呼び出すたびに、新しいスタック フレームが導入されるため、制限を高速に実行できます。TCO をサポートする適切なスキームは、実際には新しいスタック フレームを作成せず、値を更新し、現在のフレームの開始時に継続に戻ります。これにより、再帰が非常に効率的になります。

JVM で実行される clojure でさえ、この問題に悩まされています。そのため、その制限を処理するために recur と呼ばれるラムダがあります。あわせてチェック: TCOペーパー

于 2012-09-15T00:53:06.327 に答える