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 JAVA_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... ]
答案 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
答案 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