3

Java環境で奇妙なバグが発生しているようです。これで、同じ「発生しない」例外が2回発生しました。あるケースでは、実行中のプロセスで48分間に42,551回問題が発生し、その後自然に解消されました。

失敗したコードは、次の行によってトリガーされます。

return String.format("%1d%XY%d", source, System.currentTimeMillis(), quoteID);

ここでint source = 0long quoteID = 44386874(たとえば)。

例外は次のとおりです。

java.util.UnknownFormatConversionException: Conversion = 'd'
        at java.util.Formatter$FormatSpecifier.conversion(Formatter.java:2605)
        at java.util.Formatter$FormatSpecifier.<init>(Formatter.java:2633)
        at java.util.Formatter.parse(Formatter.java:2479)
        at java.util.Formatter.format(Formatter.java:2413)
        at java.util.Formatter.format(Formatter.java:2366)
        at java.lang.String.format(String.java:2770)

コードをチェックしても、'd'この例外が発生することはありません。

私たちが思いついた最も良い説明は、JITコンパイラが不正なバイトコードを生成しているということですが、その後の再JITでは、正常なコードを記述します。

誰かがそのような問題を回避/診断する方法の経験がありますか?

ロジャー。

4

6 に答える 6

7

これが正当な JIT の問題であるとは思えません。

メモリの破損やランタイム環境の問題など、他の可能性を除外しましたか?

これが JIT の問題であるとどのように結論付けましたか?

気を楽にするために、これは例外をスローしているコードです。

private char java.util.Formatter.FormatSpecifier.conversion(String s) {
    c = s.charAt(0);
    if (!dt) {
    if (!Conversion.isValid(c))
        throw new UnknownFormatConversionException(String.valueOf(c));

        ///////..........
}

と:

static boolean java.util.Formatter.Conversion.isValid(char c) {
    return (isGeneral(c) || isInteger(c) || isFloat(c) || isText(c)
        || c == 't' || c == 'c');
}

dは正当な整数識別子であり、isValid()を返す必要がありTrueます。

これをデバッグすることは問題ではありません。経験に基づいた推測では、何も見つからないことがわかります。これは明らかにメモリ破損/環境の問題です。この問題は簡単に再現できるようです。別のマシン、別の OS、別の JVM でテストしてみてください。

私の予感 - あなたの問題は JIT コンパイラーではありません。

于 2009-11-25T15:20:04.450 に答える
1

JIT バグかどうかを確認する簡単な方法は、コードをループに入れることです。JIT バグの場合、ループの内側では失敗しますが、外側では失敗しません。

for (int i = 0; i < 100000; i++) {
        String.format("%1d%XY%d", source, System.currentTimeMillis(), quoteID);
    }
于 2009-11-25T16:14:24.737 に答える
1

メモリをテストしてください!たとえば、memtest86+ を使用します。これは、Ubuntu の CD ブート メニューで利用できます。

于 2009-12-10T23:16:22.457 に答える
0

最初に行うことは、java.util.Formatterのソースコードをチェックし、「d」パターン文字の例外が発生する他のチェックが実行されているかどうかを確認することです。どのJavaバージョンを使用していますか?

于 2009-11-25T15:27:49.433 に答える
0

そのコードの「d」は本当に ASCII d であり、たまたま ad のように見える Unicode 文字ではありませんか?

(ロングショットですが、奇妙なことが起こりました。)

于 2009-11-25T15:51:38.760 に答える
0

行う:

final long time;

time = System.currentTimeMillis();

try
{
    return String.format("%1d%XY%d", source, time, quoteID);
}
catch(final UnknownFormatConversionExceptio ex)
{
    // log the source
    // log the time
    // log the quoteID
    throw ex;
}

何もおかしくない場合は、String.format のソースを見て、それらの値を使用して手動でトレースします (トレースを行ったように聞こえますが、実際の値で行うと役立つ場合があります)。

また、他の人が言っているように、ランダムなメモリのバグもここで発生する可能性があります。可能であれば、マシンでメモリ チェックを実行して確認します (メモリを取り付け直すことで問題が解消されました...)。

于 2009-11-25T15:38:45.307 に答える