これはおそらく非常に素朴な質問です。Javaでスタックトレースのない例外
私は、の には常ににスタックトレースが含まれていると考えました。それが正しいか? 今度はexceptions
を捕まえたようですが、スタックトレースはありません。それは理にかなっていますか?それは可能スタックトレースなしで例外をキャッチですか?
これはおそらく非常に素朴な質問です。Javaでスタックトレースのない例外
私は、の には常ににスタックトレースが含まれていると考えました。それが正しいか? 今度はexceptions
を捕まえたようですが、スタックトレースはありません。それは理にかなっていますか?それは可能スタックトレースなしで例外をキャッチですか?
それはスタックトレースせずにJavaでThrowableオブジェクトをキャッチすることが可能です:
Throwable(String message, Throwable cause, boolean enableSuppression,boolean writableStackTrace)
は 指定された詳細メッセージ、原因、抑制有効化または無効化、および 書き込み可能なスタックトレースで新しいスロー可能オブジェクトを構築します有効または無効です。 Java 6のために
http://docs.oracle.com/javase/7/docs/api/java/lang/Throwable.html
:
のJava 6がThrowable(String message, Throwable cause, boolean enableSuppression,boolean writableStackTrace)
コンストラクタを持っていないとして、我々は技術(スカラ座から借り、How slow are Java exceptions?から知るようになった)の下に使用してスタックトレースの充填を抑制することができます
class NoStackTraceRuntimeException extends RuntimeException {
@Override
public synchronized Throwable fillInStackTrace() {
return this;
}
}
使用方法は同じです:throw new NoStackTraceRuntimeException()
、またはそのサブタイプです。
我々はまた、Throwable
を拡張することで同じことを行うことができます。
class NoStackTraceThrowable extends Throwable {
@Override
public synchronized Throwable fillInStackTrace() {
return this;
}
}
をしかし、小さなキャッチあなたはもはやcatch
これはException
のサブタイプではないので、Exception
を使用して、これらの例外ではなく、キャッチするべきではないということですNoStackTraceThrowable
かそれはサブタイプです。
更新:異なるユースケースでのパフォーマンス上のいくつかの興味深い統計は、Java 7+については、このSO question
を確認するには、ここでのスタックトレースを任意に抑制することができる例外の一例です。
public class SuppressableStacktraceException extends Exception {
private boolean suppressStacktrace = false;
public SuppressableStacktraceException(String message, boolean suppressStacktrace) {
super(message, null, suppressStacktrace, !suppressStacktrace);
this.suppressStacktrace = suppressStacktrace;
}
@Override
public String toString() {
if (suppressStacktrace) {
return getLocalizedMessage();
} else {
return super.toString();
}
}
}
これを用いて実証することができる:これはApache SystemMLからMLContextException、https://github.com/apache/systemmlでGitHubの上で利用可能となっているコードに基づいている
try {
throw new SuppressableStacktraceException("Not suppressed", false);
} catch (SuppressableStacktraceException e) {
e.printStackTrace();
}
try {
throw new SuppressableStacktraceException("Suppressed", true);
} catch (SuppressableStacktraceException e) {
e.printStackTrace();
}
。
任意の例外にスタックトレースを抑制するための最も簡単な方法は、例外が原因を持っている場合は、再帰的に同じことを行う必要があるかもしれません
throwable.setStackTrace(new StackTraceElement[0]);
です。
はこれもできないので、任意のコンストラクタによって呼び出されたThrowableのためのスタックトレースが
Throwable#fillInStackTrace()
に初期化され
できるだけ多くのスタックトレースの高価な作成を、低減し、避けてください。 スタックトレースが実際に使用される場合、のStackTraceElement []は、レイジーフィールドThrowable.stackTraceが既に設定されていない場合にのみ、起こる
Throwable#getOurStackTrace()
に構成されています。
null以外の値にstacktraceを設定すると、Throwable#getOurStackTrace()でStackTraceElement []が構築されるのを避け、パフォーマンスペナルティをできるだけ減らします。
これは機能しますが、スタックトレースを抑制することで解決したい問題を解決することはできません。スタックトレースの生成が遅いため、メッセージングに多くの例外を使用するコードが遅くなる可能性があります。これに対処するには、スタックトレースの作成を防止し、すでに作成されている場合は削除しないようにする必要があります。 - 何らかの理由でコントロールのない多数の例外が格納されている場合でも、メモリを節約するためにはあなたのアプローチは依然として有効かもしれません。 –
Halo @Hans Adler、私はあなたの懸念を理解していますが、私の答えはスタックトレースのコストのかかる作成を可能な限り減らすと思います。私の最後の編集を見てください。 –
JVMとは?環境?これは役に立ちますか? http://stackoverflow.com/questions/4659151/recurring-exception-without-a-stack-trace-how-to-reset –
@SB。はい、これは助けになります。どうもありがとう。私は非常に似た問題があります:私は多くの例外(NPE)を持っています。 'log4j'の' error'メソッドはスタックトレースなしでいくつかの例外を記録します。 – Michael