JVM在编译线程处崩溃

3

我的Java应用程序在尝试编译特定方法时几乎总是崩溃(始终是同一个方法),出现SIGSEGV错误:

 A fatal error has been detected by the Java Runtime Environment:

  SIGSEGV (0xb) at pc=0x00002aaaab6642a5, pid=8348, tid=1087596864

 JRE version: 6.0_16-b01
 Java VM: Java HotSpot(TM) 64-Bit Server VM (14.2-b01 mixed mode linux-amd64 )
 Problematic frame:
 V  [libjvm.so+0x5332a5]

 An error report file with more information is saved as:
 hs_err_pid8348.log

 If you would like to submit a bug report, please visit:
   http://java.sun.com/webapps/bugreport/crash.jsp

崩溃日志(有趣的部分...):
 A fatal error has been detected by the Java Runtime Environment:

  SIGSEGV (0xb) at pc=0x00002aaaab6642a5, pid=8348, tid=1087596864

 JRE version: 6.0_16-b01
 Java VM: Java HotSpot(TM) 64-Bit Server VM (14.2-b01 mixed mode linux-amd64 )
 Problematic frame:
 V  [libjvm.so+0x5332a5]

 If you would like to submit a bug report, please visit:
   http://java.sun.com/webapps/bugreport/crash.jsp

---------------  T H R E A D  ---------------

Current thread (0x00002aab1f7ac800):  JavaThread "CompilerThread0" daemon [_thread_in_native, id=8694, stack(0x0000000040c36000,0x00000000
40d37000)]

我试图创建一个核心转储并连接到它,但是我找不到编译器线程(可能已被杀死)。

4个回答

2
请将整个页面(包括有关库的额外信息)以及堆栈等内容发布出来,如果可以的话。如果您看到核心转储,则无法查看任何线程。
如果问题涉及zlib(ZipEntry),那么您可能会遇到一些麻烦......这是一个非常恼人的错误,在zip处理中非常明显,如果在打开后更改了zip(jar)文件,则会发生这种情况。我仍然想知道为什么Sun/Oracle使用原生库进行zip处理,因为在纯Java中进行处理更加稳定,并且性能更快(性能方面快两倍)。

@bestsss,你说的ZipEntry - libzip.so是什么意思? - ekeren
@ekeren:我有崩溃转储,虽然有完全可重现的行为,但太阳公司认为它是:“11-关闭,无法重现,错误”。http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6366468 - bestsss
@bestsss:更令人遗憾的是,他们正在使用本地的zlib,因为它已经是至少一个安全问题(缓冲区溢出,如果他们使用Java编写的话将不可能发生)的根本原因...但也许这里有一些进退两难的境地,我不知道,还没有真正研究过。 - SyntaxT3rr0r
@SyntaxT3rr0r:不,没有任何问题,将转换为完整的Java.util.zip并用Java编写是完全可能的。也许,下次我有空闲时间时,我会将我们(公司)的应用服务器转换为使用它。 - bestsss
@SyntaxT3rr0r:回到过去,我想这可能是一个重大的性能问题,现在本地的zlib在现场测试中比jzlib慢。调用非内联JNI代码(任何自定义库)并不快。 - bestsss
显示剩余2条评论

2

手动优化所涉及的方法。

当前线程(0x00002aab1f7ac800):JavaThread "CompilerThread0"(编译器线程0)守护程序 [_thread_in_native,id = 8694,stack(0x0000000040c36000,0x0000000040d37000)]

在这行下面,您应该看到热点引擎试图优化的具体方法。 您可能遇到了一些存在问题的热点代码。 确定被触发的代码以及原因将非常困难。

我曾经遇到过这个问题,并解决了这个问题。 所涉及的方法写得非常不规范,创建了不必要的数据结构,添加了额外的循环,还创建了仅使用一次的额外变量。 我逐步优化了这个方法,直到最终迭代(几乎是琐碎的优化)后,它终于没有抛出异常。

我相信,最后有一个字节码优化例程中的错误被触发了。 几乎无法知道确切发生了什么。 但我认为通过手动优化代码,我优化了字节码,使热点引擎不再运行有问题的例程。

我知道这并不是确定的解决方法,但我希望我的经历能够帮助您和未来的访问者。 祝你好运!


你是如何使用JIT手动优化方法的?能否告诉我一下?我也遇到了同样的问题。 - Sumit Gupta
我没有使用JIT。在我的情况下,下一行提到的方法是我库中正在编译的方法。我通过删除不必要的代码和循环来优化该方法。如果该方法已经被优化,我会尝试以不同的方式拆分事物-调整算法,使步骤略有不同。 - Erick Robertson

0
JRE版本6.0_16相当古老。我建议升级到当前的JRE,这样崩溃很有可能已经被修复了。

这是我环境中最新的版本...暂时无法升级。 - duduamar
@duduamar:那么恐怕你就卡在这个问题上了。除非你想深入JVM的二进制内部(而你真的不想这样做),否则你无法调试此问题。升级JVM是唯一的解决方案。 - skaffman
@skafmman:你知道6.0_16版本中可能解释这个问题的一个已知漏洞吗? - ekeren
@ekeren:没有特别的建议。不过这是我唯一能提供的建议,而且通常会起作用。 - skaffman

0
如果可以的话,您可以通过将此参数添加到Java可执行文件调用中来从运行时中排除导致崩溃的方法:-XX:CompileCommand=exclude,com/path/to/class/in/Jar$InnerClassIfAny.methodName 导致崩溃的类和方法名称可以在崩溃报告(hs_err_pidxxxx.log)中找到,在--------------- P R O C E S S ---------------上方。
注意:在Unix环境中,内部类(如果有任何)应该像这样进行转义:\$而不是$

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接