Java 虚拟机外部发生崩溃
Joakim Nordström 于 2020 年 12 月 3 日你正在放松地享受 Minecraft 游戏,突然“Java 运行时环境检测到致命错误
”!
照片由 Cindy Tang 提供
Java 应用程序中的致命错误
任何 Java 应用程序都可能导致致命错误。要查找提示,您需要查看生成的 hs_err 文件
。以下是 运行 Minecraft 时发生的崩溃 示例。
# # A fatal error has been detected by the Java Runtime Environment: # # EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x0000000022051066, pid=2372, tid=0x00000000000017a0 # # JRE version: Java(TM) SE Runtime Environment (8.0_172-b11) (build 1.8.0_172-b11) # Java VM: Java HotSpot(TM) 64-Bit Server VM (25.172-b11 mixed mode windows-amd64 compressed oops)
# Problematic frame: # C [OpenAL64.dll+0x11066]# # Failed to write core dump. Minidumps are not enabled by default on client versions of Windows # # If you would like to submit a bug report, please visit: # http://bugreport.java.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code. # See problematic frame for where to report the bug.#
真的是 JVM 崩溃了吗?
在责怪 JVM 并向 java.com 提交错误报告之前,您需要确保真的是 Java 运行时导致了崩溃。实际上,就在错误报告链接下方,如果您看到消息:“崩溃发生在 Java 虚拟机外部的本机代码中
”,则明确表明崩溃是由其他代码(很可能是某种库)而不是 Java 虚拟机引起的。
崩溃发生在 Java 虚拟机外部
在 hs_err
文件中进一步搜索,您应该会看到字符串“查看有问题的帧以报告错误的位置
”,这表明您应该在文件中向上查找以查明问题。
…
# Problematic frame:
# C [OpenAL64.dll+0x11066]
…
查看有问题的帧,我们发现崩溃发生在 OpenAL64.dll
中,这是 Minecraft 用于处理声音的库。
堆栈跟踪
我们可以通过查看堆栈跟踪进一步分析崩溃的原因。
…
Stack: [0x000000002bf80000,0x000000002c080000], sp=0x000000002c07e980, free space=1018k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C [OpenAL64.dll+0x11066]
C [OpenAL64.dll+0x1248f]
C 0x0000000005788c67
Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j org.lwjgl.openal.ALC10.nalcCreateContext(JJ)J+0
j org.lwjgl.openal.ALC10.alcCreateContext(Lorg/lwjgl/openal/ALCdevice;Ljava/nio/IntBuffer;)Lorg/lwjgl/openal/ALCcontext;+8
j org.lwjgl.openal.AL.init(Ljava/lang/String;IIZZ)V+69
j org.lwjgl.openal.AL.create(Ljava/lang/String;IIZZ)V+246
j org.lwjgl.openal.AL.create(Ljava/lang/String;IIZ)V+5
j org.lwjgl.openal.AL.create()V+6
j paulscode.sound.libraries.LibraryLWJGLOpenAL.init()V+2
j paulscode.sound.SoundSystem.CommandNewLibrary(Ljava/lang/Class;)V+273
j paulscode.sound.SoundSystem.CommandQueue(Lpaulscode/sound/CommandObject;)Z+1206
j paulscode.sound.CommandThread.run()V+51
v ~StubRoutines::call_stub
…
我们看到有一些本机帧(前缀为 C
)在 OpenAL64 DLL 中执行。对 DLL 的调用是由 LWJGL(轻量级 Java 游戏库)从 Java 代码(前缀 j
)发出的,而 LWJGL 又由 paulscode.sound(Paulscode 的 3D 音频系统)调用。 ~StubRoutines::call_stub
是 JVM 的调用,用于从 C 代码调用 Java 方法。此堆栈跟踪还作为令人信服的证据,证明崩溃不是由于 JVM 本身的问题,因为唯一的 JVM 相关堆栈跟踪条目是 StubRoutines 调用。如果我们能够访问 OpenAL64.dll
,或者知道如何调用它,我们就可以遍历堆栈和所涉及的代码,以可能找到错误是出现在 DLL 本身、LWJGL 代码还是音频系统库中。
摘要
JVM 崩溃可能是由外部组件引起的,这些组件可能是正在运行的软件直接使用或间接相关的,例如病毒防护或其他系统软件。在这些情况下,向 java.com 提交错误报告不太可能提供帮助。第一步是通过查看 hs_err 文件
中的有问题帧来找到真正的罪魁祸首,然后采取相应措施,例如向相应所有者报告问题。