java.io.PrintStream.writeでのJavaにStackOverflowError(PrintStream.java:480)となし、さらにスタックトレース

JNWolf:

私は、10倍長い入力ファイル、おおよそ次のランタイムを例えば、プログラムが最初にするために設計されたよりも多くのデータを別の人によって書かれたJavaプログラムを実行しています。私は別の問題に遭遇し、今彼らが少しずつ解決することを目指しています。

出力の多くは、すでに印刷された実行(ファイルにリダイレクト)の間、私は次の取得の出力を:

Exception in thread "main" java.lang.StackOverflowError  
        at java.io.PrintStream.write(PrintStream.java:480)  
        [...]  
        at java.io.PrintStream.write(PrintStream.java:480)

スタックトレースは、それが何度も何度もちょうど同じ行の長い繰り返しであるとして私を混乱させる最初のものです。さらに、それは、コードまたは実行中に問題が発生した意図を与えません。

私の考え/研究

  • StackOverflowErrorが
    • あまりにも少ないメモリを示すことがあります。-Xmx110GフラグとI 110 Gメモリを提供し、実行しながら、それを監視し、唯一のアップ〜32 Gに使用しました。だから、これは、ここではおそらく問題ではありません。
    • 無限ループの原因となるミスをプログラミングによるスローされてもよいです。私は私がコード内の問題の場所を見つける助けにはならないコードとスタックトレースでおなじみの足りないよしかし、私は本当にこれをチェック傾けます。
    • 出力の書き込みが実行され、新しい印刷/書き込み呼び出しよりも遅いため、[仮説]、発生することがあります。それでも、なぜそれ以上のスタックトレースはありませんか?どのように私はこれをチェックし、修正することができますか?
  • PrintStream

    • 「PrintStreamを」を検索した後にのみコードフラグメント

      // reset output stream to suppress the annoying output of the Apache batik library. Gets reset after lib call.  
      OutputStream tmp=System.out;  
      System.setOut(new PrintStream(new org.apache.commons.io.output.NullOutputStream()));  
      drawRes.g2d.stream(new FileWriter(svgFilePath), false);      
      System.setOut(new PrintStream(tmp));  
      
    • [仮説]のボイド/ nullに書き込みが仕事をしません
    • [回避策]出力ストリームの変更やプログラムの開発を作成し、大きな出力を持つだけで「ライブ」をスキップする場合は、実行するようです(他の問題に、これは別のケースです)。すべてのアイデアは、なぜこれが起こっているのでしょうか?

アドバイスのための呼び出しは、
Javaコードは、特に何をするか1に何が起こっている上の任意のアドバイスを、持っている場合、私はそれを理解する助けてください。それは固定を開始する場所を提供しないよう特にスタックトレースは私を失望させます。私はStackOverflowの、などを避けるためにコードを修正し、また、この問題に取り組むスタックトレースを取得する方法についての一般的なアプローチのために感謝しています

一部のシステム環境の事実

  • Linuxマシン
  • 128 Gメモリ
  • ジャワ

    openjdk version "1.8.0_121"  
    OpenJDK Runtime Environment (IcedTea 3.3.0) (suse-28.1-x86_64)  
    OpenJDK 64-Bit Server VM (build 25.121-b13, mixed mode)
    
  • あなたはより多くの情報が必要な場合はお問い合わせください!

ノート

  • 私は(プログラムは私が書かれていない)すべてのアドバイスに感謝していますので、私は、Javaにかなり新しいです
  • 私が尋ねると、フォーマットの自分のスタイルを向上させることができる場所これはstackoverflowの上の私の最初の投稿です、私にご連絡ください
  • 私は英語のネイティブスピーカー午前、そうしてください言い訳ミスや理解や正しい私のためにお気軽に

すべての返信をありがとう!

トーマス・申請者:

これらの2行は、不審に見えます:

OutputStream tmp=System.out;
//...
System.setOut(new PrintStream(tmp));

System.outすでにあるPrintStream行は読みくださいIMHOので、

PrintStream tmp=System.out;
//...
System.setOut(tmp);

何が起こるかは、そうでない場合は、あなたがの近くに無限のラッピング持っているということですPrintStream内のPrintStream秒。PrintStreamsのネスティングが唯一のJavaヒープ空間を限定されている-しかし、コール・レベル・ネスティングははるかに低いです。


仮説を検証するために、私は最初のラップという小さなテストプログラムを作成したSystem.out20回と呼び出しチェーンを検証するためにスタックトレースを出力します。その後、それはラップSystem.out10_000回とStackOverflowExceptionがを生成します。

import java.io.OutputStream;
import java.io.PrintStream;

public class CheckPrintStream {
    public static void main(String[] args) {
        PrintStream originalSystemOut = System.out;
        System.setOut(new PrintStream(System.out) {
            @Override
            public void write(byte buf[], int off, int len) {
                originalSystemOut.write(buf, off, len);
                if (len > 2) {
                    new RuntimeException("Testing PrintStream nesting").printStackTrace(originalSystemOut);
                }
            }
        });

        for (int i = 0; i < 20; i++) {
            wrapSystemOut();
        }
        System.out.println("Hello World!");

        for (int i = 20; i < 10_000; i++) {
            wrapSystemOut();
        }
        System.out.println("crash!");
    }

    private static void wrapSystemOut() {
        OutputStream tmp = System.out;
        System.setOut(new PrintStream(System.out));
    }
}

周り6000 7000 PrintWritersのネスティングは、スタックオーバーフローを生成するのに十分です。

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=137917&siteId=1