解决Java JIT错误

时间:2009-11-25 15:14:42

标签: java jit

我们似乎在Java环境中遇到了一个奇怪的错误。 我们现在有两次相同的“不可能发生”的例外;在一个案例中,问题在一个运行过程中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中,它编写了良好的代码。

任何人都有解决此类问题的方法吗?

罗杰。

6 个答案:

答案 0 :(得分: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

调试这不是问题,一个有根据的猜测会说你什么都找不到。这显然是内存损坏/环境问题。听起来这个问题很容易复制。尝试在不同的机器,不同的操作系统,不同的JVM上进行测试。

我的预感 - 你的问题不是JIT编译器。

答案 1 :(得分:1)

检查它是否是JIT错误的简单方法是将代码放入循环中。如果它是JIT错误,它将在循环内失败但不在外面:

for (int i = 0; i < 100000; i++) {
        String.format("%1d%XY%d", source, System.currentTimeMillis(), quoteID);
    }

答案 2 :(得分:1)

测试内存!例如。用memtest86 +。它可以在Ubuntu cd启动菜单中找到。

答案 3 :(得分:0)

我要做的第一件事是检查java.util.Formatter的源代码,看看是否有任何其他检查执行导致'd'模式字符的异常。您使用的是哪个Java版本?

答案 4 :(得分: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的源代码并手动跟踪这些值(听起来您可能已经完成了跟踪,但使用实际值进行操作可能有所帮助)。 / p>

正如其他人所说,这里也可能存在随机内存错误。如果可能的话,在机器上进行内存检查并查看(我已经通过重新安装内存来解决问题......)。

答案 5 :(得分:0)

您确定该代码中的“d”是否真的是ASCII d而不是某些看起来像d的Unicode字符?

(远射,但发生了一些奇怪的事情。)