解决 Java JIT 错误

发布于 2024-08-12 02:03:07 字数 947 浏览 3 评论 0原文

我们的 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 中,它编写了良好的代码。

任何人都有解决/诊断此类问题的方法的经验吗?

罗杰.

We seem to be subject to a strange bug in our Java environment.
We've now had two occurrences of the same "can't happen" exception; in one case the problem occurred 42,551 times over a period of 48 minutes in a running process and then spontaneously cleared itself.

The failing code is triggered by this line:

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

where int source = 0 and long quoteID = 44386874 (for example).

The exception is:

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)

Checking the code 'd' should never raise this exception.

The best explanation we've come up with is that the JIT compiler is generating bad bytecode, but on a subsequent re-JIT it writes good code.

Anyone have any experience of ways to work around / diagnose such a problem?

Roger.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

凉宸 2024-08-19 02:03:07

我怀疑这是一个合法的 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));

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

with:

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 编译器。

I doubt this is a legit JIT issue.

Have you ruled out other possibilities such as memory corruption or runtime environment issues?

How did you conclude that this is a JIT problem?

Just to ease your mind, this is the code that is throwing the exception:

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));

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

with:

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

d is a legit integer identifier, and isValid() should return with True.

Debugging this is not the problem, and an educated guess will say that you will find nothing. This is clearly a memory corruption/environment issue. It sounds like this issue is easily reproduced. Try testing on a different machine, different OS, different JVM.

My hunch - your problem is not the JIT compiler.

浮云落日 2024-08-19 02:03:07

考验记忆力!例如,使用 memtest86+。它可以在 Ubuntu CD 启动菜单上找到。

Test the memory! E.g. with memtest86+. It is avaliable on the Ubuntu cd boot menu.

甜宝宝 2024-08-19 02:03:07

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

(可能性不大,但更奇怪的事情发生了。)

Are you sure the "d"s in that code are really ASCII d's and not some Unicode character that happens to look like a d?

(A long shot, but stranger things have happened.)

暖阳 2024-08-19 02:03:07

检查是否是 JIT bug 的一个简单方法是将代码放入循环中。如果是 JIT bug,它将在循环内部失败,但在外部不会失败:

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

An easy way to check if it is a JIT bug is to put you code in a loop. If it is a JIT bug it will fail inside the loop but not outside :

for (int i = 0; i < 100000; i++) {
        String.format("%1d%XY%d", source, System.currentTimeMillis(), quoteID);
    }
走走停停 2024-08-19 02:03:07

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

The first thing I would do is to check the source code of java.util.Formatter and see if there is any other checks performed resulting in an exception for the 'd' pattern character. Which Java version are you using?

甜妞爱困 2024-08-19 02:03:07

做:

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 的源代码,并使用这些值手动跟踪它(听起来您可能已经完成了跟踪,但使用实际值进行跟踪可能会有所帮助)。

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

Do:

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;
}

If nothing looks odd there then look at the source for String.format and trace through it, by hand, with those values (sounds like you may have done the tracing, but doing it with the actual values might help).

And as others have said, random memory bugs are also possible here. If possible run a memory check on the machine and see (I have had issues go away by re-seating the memory...).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文