If a crash occurs with a critical application, and the crash appears to be caused by a bug in the HotSpot VM, then it might be desirable to quickly find a temporary workaround. The purpose of this section is to suggest some possible workarounds. If the crash occurs with an application that is deployed with the most recent release of the JDK, then the crash should always be reported to Oracle.
WARNING: Even if a workaround in this section successfully eliminates a crash, the workaround is not a fix for the problem, but merely a temporary solution. Submit a support call or bug report with the original configuration that demonstrated the issue. |
The following are three scenarios to find workarounds for system crashes.
If the fatal error log indicates that the crash occurred in a compiler thread, then it is possible (but not always the case) that you have encountered a compiler bug. Similarly, if the crash is in compiled code then it is possible that the compiler has generated incorrect code.
In case of the HotSpot Client VM (-client
option), the compiler thread appears in the error log as CompilerThread0
. With the HotSpot Server VM there are multiple compiler threads and these appear in the error log file as CompilerThread0
, CompilerThread1
, and AdapterThread
.
Since JDK 7u5 release, the HotSpot compiler is ignored by default. A command line option is available to simulate the old behavior, which is useful when multiple methods have been excluded. For details on the command line option, see notable bug fixes in JDK 7u5.
To exclude methods from being compiled by using a JVM flag instead of .hotspot_compile
file, see -XX:CompileCommand
in Advanced JIT Compiler Options.
Example 5-5 shows a fragment of an error log for a compiler bug that was encountered and fixed during the development. The log file shows that the HotSpot Server VM is used and the crash occurred in CompilerThread1
. In addition, the log file shows that the current CompileTask
was the compilation of the java.lang.Thread.setPriority
method.
Example 5-5 Error Log for a Compiler Bug
# An unexpected error has been detected by HotSpot Virtual Machine: # : # Java VM: Java HotSpot(TM) Server VM (1.5-internal-debug mixed mode) : --------------- T H R E A D --------------- Current thread (0x001e9350): JavaThread "CompilerThread1" daemon [_thread_in_vm, id=20] Stack: [0xb2500000,0xb2580000), sp=0xb257e500, free space=505k Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code) V [libjvm.so+0xc3b13c] : Current CompileTask: opto: 11 java.lang.Thread.setPriority(I)V (53 bytes) --------------- P R O C E S S --------------- Java Threads: ( => current thread ) 0x00229930 JavaThread "Low Memory Detector" daemon [_thread_blocked, id=21] =>0x001e9350 JavaThread "CompilerThread1" daemon [_thread_in_vm, id=20] :
In this case there are two potential workarounds:
The brute force approach: change the configuration so that the application is run with the -client
option to specify the HotSpot Client VM.
The subtle approach: assume that the bug only occurs during the compilation of the java.lang.Thread.setPriority
method and exclude this method from compilation.
The first approach (to use the -client
option) might be trivial to configure in some environments. In others, it might be more difficult if the configuration is complex or if the command line to configure the VM is not readily accessible. In general, switching from the HotSpot Server VM to the HotSpot Client VM also reduces the peak performance of an application. Depending on the environment, this might be acceptable until the actual issue is diagnosed and fixed.
The second approach (exclude the method from compilation) requires creating the file .hotspot_compiler in the working directory of the application. Example 5-6 shows this approach.
In general the format of this file is exclude
class method, where class is the class (fully qualified with the package name) and method is the name of the method. Constructor methods are specified as <init>
and static initializers are specified as <clinit>
.
Note: The .hotspot_compiler file is an unsupported interface. It is documented here solely for the purposes of troubleshooting and finding a temporary workaround. |
Once the application is restarted, the compiler will not attempt to compile any of the methods excluded in the .hotspot_compiler file. In some cases this can provide temporary relief until the root cause of the crash is diagnosed and the bug is fixed.
In order to verify that the HotSpot VM correctly located and processed the .hotspot_compiler file that is shown in Example 5-6, look for the log information at runtime. Note: The file name separator is a dot, not a slash.
If a crash occurs during garbage collection (GC), then the fatal error log reports that a VM_Operation
is in progress. For the purposes of this discussion, assume that the mostly concurrent GC (-XX:+UseConcMarkSweep
) is not in use. The VM_Operation
is shown in the THREAD
section of the log and indicates one of the following situations:
Generation collection for allocation
Full generation collection
Parallel gc failed allocation
Parallel gc failed permanent allocation
Parallel gc system gc
Most likely the current thread reported in the log is the VMThread
. This is the special thread used to execute special tasks in the HotSpot VM. Example 5-7 is a fragment of the fatal error log from a crash in the serial garbage collector.
Example 5-7 Crash in Serial Garbage Collector
--------------- T H R E A D --------------- Current thread (0x002cb720): VMThread [id=3252] siginfo: ExceptionCode=0xc0000005, reading address 0x00000000 Registers: EAX=0x0000000a, EBX=0x00000001, ECX=0x00289530, EDX=0x00000000 ESP=0x02aefc2c, EBP=0x02aefc44, ESI=0x00289530, EDI=0x00289530 EIP=0x0806d17a, EFLAGS=0x00010246 Top of Stack: (sp=0x02aefc2c) 0x02aefc2c: 00289530 081641e8 00000001 0806e4b8 0x02aefc3c: 00000001 00000000 02aefc9c 0806e4c5 0x02aefc4c: 081641e8 081641c8 00000001 00289530 0x02aefc5c: 00000000 00000000 00000001 00000001 0x02aefc6c: 00000000 00000000 00000000 08072a9e 0x02aefc7c: 00000000 00000000 00000000 00035378 0x02aefc8c: 00035378 00280d88 00280d88 147fee00 0x02aefc9c: 02aefce8 0806e0f5 00000001 00289530 Instructions: (pc=0x0806d17a) 0x0806d16a: 15 08 83 3d c0 be 15 08 05 53 56 57 8b f1 75 0f 0x0806d17a: 0f be 05 00 00 00 00 83 c0 05 a3 c0 be 15 08 8b Stack: [0x02ab0000,0x02af0000), sp=0x02aefc2c, free space=255k Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code) V [jvm.dll+0x6d17a] V [jvm.dll+0x6e4c5] V [jvm.dll+0x6e0f5] V [jvm.dll+0x71771] V [jvm.dll+0xfd1d3] V [jvm.dll+0x6cd99] V [jvm.dll+0x504bf] V [jvm.dll+0x6cf4b] V [jvm.dll+0x1175d5] V [jvm.dll+0x1170a0] V [jvm.dll+0x11728f] V [jvm.dll+0x116fd5] C [MSVCRT.dll+0x27fb8] C [kernel32.dll+0x1d33b] VM_Operation (0x0373f71c): generation collection for allocation, mode: safepoint, requested by thread 0x02db7108
Note: A crash during garbage collection does not imply a bug in the garbage collection implementation. It could also indicate a compiler or runtime bug, or some other issue. |
You can try the following workarounds if you get a repeated crash during garbage collection:
Switch GC configuration. For example, if you are using the serial collector, try the throughput collector, or visa versa.
If you are using the HotSpot Server VM, try the HotSpot Client VM.
If you are not sure which garbage collector is in use, you can use the jmap
utility on Oracle Solaris and Linux operating systems. See The jmap Utility to obtain the heap information from the core file, if the core file is available. In general if the GC configuration is not specified on the command line, then the serial collector will be used on Windows. On Oracle Solaris and Linux operating systems it depends on the machine configuration. If the machine has at least 2 GB of memory and has at least 2 CPUs, then the throughput collector (Parallel GC) will be used. For smaller machines the serial collector is the default. The option to select the serial collector is -XX:+UseSerialGC
and the option to select the throughput collector is -XX:+UseParallelGC
. If, as a workaround, you switch from the throughput collector to the serial collector, then you might experience some performance degradation on multi-processor systems. This might be acceptable until the root issue is diagnosed and resolved.
Class data sharing (CDS) was a new feature in J2SE 5.0. When the JRE is installed on 32-bit platforms using the Sun-provided installer, the installer loads a set of classes from the system JAR file into a private internal representation and dumps that representation to a file called a shared archive. When the VM is started, the shared archive is memory-mapped in. This saves on class loading and allows much of the metadata associated with the classes to be shared across multiple VM instances. In J2SE 5.0, CDS is enabled only when the HotSpot Client VM is used. In addition, sharing is supported only with the serial garbage collector.
The fatal error log prints the version string in the header of the log. If sharing is enabled, it is indicated by the text "sharing", as shown in Example 5-8.
Example 5-8 Error Log for Class Data Sharing
# An unexpected error has been detected by HotSpot Virtual Machine: # # EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x08083d77, pid=3572, tid=784 # # Java VM: Java HotSpot(TM) Client VM (1.5-internal mixed mode, sharing) # Problematic frame: # V [jvm.dll+0x83d77]
CDS can be disabled by providing the -Xshare:off
option on the command line. If the crash only occurs with sharing enabled, then it is possible that you have encountered a bug in this feature. In that case gather as much information as possible and submit a bug report.