此错误意味着sun.misc.Unsafe.getX()或putX()内存访问导致
SIGBUS错误,然后由JVM捕获并转换为异步InternalError.
更多细节:
> sun.misc.Unsafe是JDK私有API,允许直接从Java访问本机内存.此API是Direct ByteBuffers的基础,特别是MappedByteBuffers.
>在某些情况下,访问文件的内存映射区域可能会导致操作系统级异常,即SIGBUS.典型的例子是:
>在截断基础文件后访问内存映射缓冲区.
>网络驱动器上的文件已映射到内存,并且在网络连接丢失后访问映射的缓冲区.
>尝试写入映射到tmpfs文件系统上的文件的页面会导致内存不足(默认情况下,tmpfs空间受限于总RAM的50%).
> HotSpot JVM无法事先有效地检测到这些问题.它将Unsafe.getX / putX调用编译为简单的内存访问指令.检查内存区域是否有效的附加检查太昂贵了.
>而是JVM处理SIGBUG信号.如果它在Unsafe调用中发现错误,它会将InternalError发布到当前线程并继续执行.
> IOException更合适,但JVM不能抛出它或任何其他异常,因为ByteBuffer公共契约不允许其get / put方法抛出任何异常.
>如果在JIT编译的方法中不安全的内存访问失败,JVM不会立即抛出异常(同样,对于这样的热ByteBuffer API来说,它会太昂贵).相反,它将异步InternalError发布到当前线程.这意味着错误实际上会抛出最近的本机方法或最近的VM运行时调用.因此错误消息中的“最近”一词.