解决javajit错误
在Java环境中,我们似乎遇到了一个奇怪的bug。 我们现在已经发生了两次相同的“不可能发生”异常;在一个案例中,问题在运行过程中48分钟内发生42551次,然后自动清除 失败代码由以下行触发:解决javajit错误,java,jit,Java,Jit,在Java环境中,我们似乎遇到了一个奇怪的bug。 我们现在已经发生了两次相同的“不可能发生”异常;在一个案例中,问题在运行过程中48分钟内发生42551次,然后自动清除 失败代码由以下行触发: return String.format("%1d%XY%d", source, System.currentTimeMillis(), quoteID); 其中int source=0和long quoteID=44386874(例如) 例外情况是: java.util.UnknownFormatC
return String.format("%1d%XY%d", source, System.currentTimeMillis(), quoteID);
其中int source=0
和long 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)
java.util.UnknownFormatConversionException:Conversion='d'
在java.util.Formatter$FormatSpecifier.conversion(Formatter.java:2605)
位于java.util.Formatter$FormattSpecifier。(Formatter.java:2633)
位于java.util.Formatter.parse(Formatter.java:2479)
位于java.util.Formatter.format(Formatter.java:2413)
位于java.util.Formatter.format(Formatter.java:2366)
位于java.lang.String.format(String.java:2770)
检查代码'd'
不应引发此异常
我们得出的最好的解释是,JIT编译器正在生成错误的字节码,但在随后的重新JIT中,它编写了良好的代码
有没有人有解决/诊断此类问题的经验
罗杰。我怀疑这是一个合法的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));
///////..........
}
与:
d
是合法整数标识符,isValid()
应返回True
调试这不是问题,一个有根据的猜测会说你什么也找不到。这显然是内存损坏/环境问题。听起来这个问题很容易复制。尝试在不同的机器、不同的操作系统、不同的JVM上进行测试
我的直觉-您的问题不是JIT编译器。我要做的第一件事是检查java.util.Formatter的源代码,看看是否执行了任何其他检查,导致“d”模式字符出现异常。您使用的是哪个Java版本?请执行以下操作:
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的源代码,并用这些值手动跟踪它(听起来您可能已经完成了跟踪,但用实际值进行跟踪可能会有所帮助)
正如其他人所说,这里也可能出现随机内存错误。如果可能的话,在机器上运行一次内存检查,然后查看(我遇到的问题可以通过重新放置内存来解决…。您确定代码中的“d”是真正的ASCII d,而不是一些看起来像d的Unicode字符吗
(很长一段时间,但奇怪的事情发生了。)检查它是否是JIT错误的一个简单方法是将代码放入循环中。如果是JIT错误,它将在循环内失败,但不会在循环外失败:
for (int i = 0; i < 100000; i++) {
String.format("%1d%XY%d", source, System.currentTimeMillis(), quoteID);
}
for(int i=0;i<100000;i++){
String.format(“%1d%XY%d”,source,System.currentTimeMillis(),quoteID);
}
测试内存!例如,使用memtest86+。它可以在Ubuntu cd启动菜单上找到。不,我们不排除任何可能性。考虑到故障的性质(并且程序是纯Java的),到目前为止,JIT错误是我们最有可能的猜测。我们可能有一个JVM内存错误,但它自动清除的事实似乎符合jit问题。事实上,它是零星的,而且非常非常奇怪,这是一个硬件问题。JIT编译器、JVM环境中的错误虽然可能,但可能性很小。哪个JVM?您是否尝试使用包含该行的方法来更改JIT处理?您是否尝试过显式索引以查看是否有帮助?“X”格式不是十六进制数,而“Y”格式不是一年吗?如果你认为这是一个合法的错误,那么你应该向Sun提交一些东西,以便他们能够调查并(可能)修复它。你应该在第一时间提到你正在使用JRockit。我们已经检查了源代码,我们正在使用jrockit R27.6.0-50_o-100423-1.6.0_05-20080626-2104-linux-x86_64。Formatter.java的1.6源代码在Conversion.isValid(c)失败时抛出,当isInteger(char c)返回true时,它应该返回true,因为“d”是十进制整数。如果它是一个不正确的格式代码,那么代码开始工作,然后停止,然后重新启动将是很奇怪的!你有jrockit的来源吗?这不是来自Oracle的专有JVM吗?不,我们有java类的sun源代码,行号似乎与我们得到的调用堆栈相匹配:-)唉,我们尝试使用已知的错误值[可从进程的完整日志文件获得]运行它,但没有成功地重现故障。请注意,鉴于调用堆栈的位置,当问题发生时,我们正在创建FormatSpecifier的代码中,查看(固定)格式字符串“%1d%XY%d”,很遗憾,它似乎并不一致——如果它是一个jit错误,它看起来是一个执行路径相关的错误。这是当今jit工作方式的过于简单的模型。JIT在编译什么、内联和何时编译方面做出了异常复杂的决策。
for (int i = 0; i < 100000; i++) {
String.format("%1d%XY%d", source, System.currentTimeMillis(), quoteID);
}