JVM崩溃问题框架:Canonicalizer :: do_If

时间:2016-10-29 16:30:00

标签: crash jvm canonical-link

Iam在启用hotdeploy时一直面临JVM崩溃(在启动时使用以下java选项 JAVA_OPTS -Xmx4096m -XX:MetaspaceSize = 512m -XX:+ HeapDumpOnOutOfMemoryError -XX:HeapDumpPath = crash -XX:ThreadStackSize = 512 -XX :+ UseConcMarkSweepGC -XX:ParallelGCThreads = 5 -XX:NewRatio = 2 -XX:+ UnlockDiagnosticVMOptions -XX:-UseLoopPredicate -Xdebug -Xrunjdwp:transport = dt_socket,address = $ DEBUG_PORT,server = y,suspend = n -XX:NewRatio = 2 -Dspringloaded.synchronize = true J​​AVA_OPTS =`echo $ JAVA_OPTS -Dspringloaded.synchronize = true -javaagent:springloaded-1.2.1.jar -noverify

环境:JDK 1.8 U 66,RHEL 6.7


    #
    # A fatal error has been detected by the Java Runtime Environment:
    #
    #  SIGSEGV (0xb) at pc=0x00007faee9a1e27c, pid=27208, tid=140379827795712
    #
    # JRE version: Java(TM) SE Runtime Environment (8.0_66-b17) (build 1.8.0_66-b17)
    # Java VM: Java HotSpot(TM) 64-Bit Server VM (25.66-b17 mixed mode linux-amd64 )
    # Problematic frame:
    # V  [libjvm.so+0x35027c]  Canonicalizer::do_If(If*)+0x1c
    #
    # Core dump written. Default location:  core.27208
    #
    # An error report file with more information is saved as:
    # hs_err_pid27208.log
    # [ timer expired, abort... ]

3 个答案:

答案 0 :(得分:3)

我在Java选项列表中注意到了-javaagent-noverify

看起来springloaded代理会生成无效的字节码,而字节码验证则明确关闭。毫不奇怪,这可能导致不可预测的结果,包括JVM崩溃。

这不是JVM问题,但很可能是springloaded代理中的错误。尝试删除-noverify选项。

-XX:-TieredCompilation也可以解决此特定问题,但如果字节码无法通过验证,请不要期望应用程序正常工作。最好远离有缺陷的代理库。

答案 1 :(得分:0)

  

4.2.1 HotSpot编译器线程或编译代码崩溃

     

如果致命错误日志表明崩溃发生在编译器中   线程,那么你有可能(但并非总是如此)   遇到编译器错误。同样,如果崩溃是在编译中   代码然后编译器可能生成错误   代码。

     

对于HotSpot Client VM(-client选项),编译器   线程在错误日志中显示为CompilerThread0。使用HotSpot   服务器VM有多个编译器线程,这些线程出现在   错误日志文件为CompilerThread0,CompilerThread1和AdapterThread。

     

下面是编译器错误的错误日志片段   在J2SE 5.0的开发过程中遇到并修复了。日志文件   显示使用了HotSpot Server VM并且发生了崩溃   CompilerThread1。另外,日志文件显示Current   CompileTask是java.lang.Thread.setPriority的编译   方法

     

HotSpot虚拟机检测到意外错误:   :   Java VM:Java HotSpot(TM)服务器VM(1.5内部调试混合模式):   --------------- T H R E A D ---------------

     

当前线程(0x001e9350):JavaThread“CompilerThread1”守护程序   [_thread_in_vm,id = 20]

     

堆栈:[0xb2500000,0xb2580000),sp = 0xb257e500,可用空间= 505k   本机帧:(J =已编译的Java代码,j =已解释,Vv = VM代码,   C =本机代码)V [libjvm.so + 0xc3b13c]:

     

Current CompileTask:opto:11 java.lang.Thread.setPriority(I)V   (53字节)

     

--------------- P R O C E S S ---------------

     

Java线程:( =>当前线程)0x00229930 JavaThread“低   内存检测器“守护进程[_thread_blocked,id = 21]   => 0x001e9350 JavaThread“CompilerThread1”守护程序[_thread_in_vm,id = 20]:

     

在这种情况下,有两种可能的解决方法:

The brute force approach: change the configuration so that the application is run with the -client option to specify the HotSpot
     

客户端虚拟机。

Assume that the bug only occurs during the compilation of the setPriority method and exclude this method from compilation.
     

第一种方法(使用-client选项)可能很简单   在某些环境中配置。在其他情况下,可能会更困难   如果配置很复杂或者要配置命令行   VM无法轻松访问。一般来说,从切换   HotSpot Server VM到HotSpot客户端VM也会降低峰值   应用程序的性能。这取决于环境   在确定并修复实际问题之前,可能会接受。

     

第二种方法(从编译中排除方法)需要   在。的工作目录中创建文件.hotspot_compiler   应用。以下是此文件的示例:

     

排除java / lang / Thread setPriority

     

一般来说,这个文件的格式是排除CLASS METHOD,其中   CLASS是类(完全限定包名)和METHOD   是方法的名称。构造方法指定为   和静态初始值设定项指定为。

     

注意 - .hotspot_compiler文件是不受支持的界面。它是   此处记录的仅用于故障排除和查找   临时解决方法。

     

重新启动应用程序后,编译器将不会尝试   编译.hotspot_compiler中列出的任何排除方法   文件。在某些情况下,这可以提供临时缓解,直到根   诊断崩溃的原因并修复错误。

     

为了验证HotSpot VM是否已正确定位和处理   看看上面例子中显示的.hotspot_compiler文件   用于运行时的以下日志信息。请注意文件名   separator是一个点,而不是斜线。

     

排除编译:java.lang.Thread :: setPriority

Source

答案 2 :(得分:0)

同意@apangin,在程序中你正在进行字节码入侵(-agent)但是指定了-noverify。验证关闭后,您可能会遇到此类崩溃。

在字节代码入门期间,不应使用-noverify或-Xverify:none。

对于那些不熟悉字节码验证的人来说,它只是JVM的类加载过程的一部分,它检查代码是否存在某些危险和不允许的行为。您可以(但不应该)通过在Java命令行中添加-Xverify:none或-noverify来禁用许多JVM上的此保护。 https://blogs.oracle.com/buck/entry/never_disable_bytecode_verification_in