我们似乎在Java环境中遇到了一个奇怪的错误。 我们现在有两次相同的“不可能发生”的例外;在一个案例中,问题在一个运行过程中48分钟内发生了42,551次,然后自发地自行清除。
失败的代码由此行触发:
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)
检查代码'd'
不应该引发此异常。
我们提出的最佳解释是JIT编译器生成了错误的字节码,但在随后的重新JIT中,它编写了良好的代码。
任何人都有解决此类问题的方法吗?
罗杰。
答案 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字符?
(远射,但发生了一些奇怪的事情。)