SSブログ

再帰の誘い [日記]

とあるWWWアプリケーションで使っているJava実行環境を1.3から5.0に変更しました。

テストも一通り終り、本番環境で動かしてみると、動作が変だ。
なんとなく、例外を投げて途中で止まっているっぽい。今まで動いていたのに。

そこで、怪しそうな場所を

try {
    ~~
} catch (Exception e) {
    e.printStackTrace();
}

で囲ってみた。

結果。変らず。スタックトレースの出力も無し。

小一時間程悩んでから、Servletコンテナ(ぶっちゃけTomcat)のログを確認することに(普通は真っ先にコレを確認するべきだ)

すると、StackOverflowError が出ている。
あー。
そりゃ、

try {
    ~~
} catch (Exception e) {
    e.printStackTrace();
}

じゃ駄目だ。

さて、

StackOverflowErrorが出るのは、大抵、再帰呼び出しの終了条件が間違っているのが原因。解りやすい理由でよかった。
でも、今まで動いていたんだけどな、これ。

改めて例外の発生場所を突き止めると、こんな感じ。

public class example
{
    BufferedReader in = new BufferedReader(new FileReader("○○"));
    
    public String get() throws IOException
    {
        String str = in.readLine();
        if (str == null)
            return "";

        return str + get();
    }
}

ファイルからデータを1行ずつ読んで、連結して返す関数です。
大体3000行くらいのファイルを読ませたら、スタックが溢れました。

テストの時は、小さいファイルを使ってたから問題なかったのか。
Java 1.3の時は同じデータでもちゃんと動いたけど………スタックの総量が多かったのか、関数呼び出し1回で消費するスタックが少ないのか……?。

とにかく、
典型的な再帰の無駄遣いですな、これは。

まぁ、気持ちは解る。

再帰呼び出しを覚えると、とりあえず再帰で実装してみたり、
C++でテンプレートに値が指定できる事とテンプレートの部分特殊化を覚えると、無駄にテンプレートプログラミング(コンパイルタイムプログラミングとも言う)してみたり、
リストの畳み込み演算を覚えると、何でもかんでも畳み込み演算で実現してみたりしますからねぇ……。

フリークス

  • 作者: 綾辻 行人
  • 出版社/メーカー: 光文社
  • 発売日: 2000/03
  • メディア: 文庫
[新幹線] 今日の一冊
フリークス (光文社文庫)

フリークス

  • 作者: 綾辻 行人
  • 出版社/メーカー: 光文社
  • 発売日: 2000/03
  • メディア: 文庫

タグ:Java
nice!(0)  コメント(0)  トラックバック(0) 

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。