I was wondering if some of the JVM gurus out there can briefly explain the following error. What does it actually mean in technical terms and what are the sequences of events that can lead to this error?
java.lang.InternalError: a fault occurred in a recent unsafe memory access operation in compiled Java code
Advertisement
Answer
This error means that sun.misc.Unsafe.getX() or putX() memory access resulted in SIGBUS error, which was then caught by JVM and translated to asynchronous InternalError.
A bit more details:
sun.misc.Unsafeis JDK private API that allows to access native memory directly from Java. This API is a foundation for Direct ByteBuffers and particularly MappedByteBuffers.In certain cases an access to memory-mapped region of a file may lead to OS-level exception, namely
SIGBUS. Typical examples are:- A memory-mapped buffer is accessed after the underlying file has been truncated.
- A file on a network drive has been mapped to memory, and the mapped buffer is accessed after the network connection has been lost.
- An attempt to write to a page mapped to a file on
tmpfsfilesystem results in out-of-memory (by defaulttmpfsspace is limited by 50% of total RAM).
HotSpot JVM cannot efficiently detect these problems beforehand. It compiles
Unsafe.getX / putXcalls to a simple memory access instruction. Additional checks to see if a memory region is valid would be too expensive.- Instead JVM handles
SIGBUGsignal. If it sees the error has happened inUnsafecall, it postsInternalErrorto current thread and continues execution. IOExceptionwould be more appropriate, but JVM cannot throw it or any other exception, sinceByteBufferpublic contract does not allow itsget/putmethods to throw any exception.- If
Unsafememory access has failed in JIT-compiled method, JVM does not throw an exception immediately (again, it would be too expensive for such hot ByteBuffer API). Instead it posts asynchronousInternalErrorto the current thread. It means the error would be actually thrown at the nearest native method or at the nearest call to VM runtime. Hence the word “recent” in the error message.
See JDK-4454115 comments describing the solution for the related JDK bug.