java.lang.InternalError:编译的Java代码中最近的不安全内存访问操作中发生了错误

wFa*_*eem 4 java memory jvm

我想知道是否有一些JVM专家可以简要解释以下错误.它在技术术语中实际意味着什么以及导致此错误的事件序列是什么?

java.lang.InternalError: a fault occurred in a recent unsafe memory access operation in compiled Java code
Run Code Online (Sandbox Code Playgroud)

apa*_*gin 11

此错误意味着sun.misc.Unsafe.getX()putX()内存访问导致SIGBUS错误,然后由JVM捕获并转换为异步InternalError.

更多细节:

  • sun.misc.Unsafe是JDK私有API,允许直接从Java访问本机内存.此API是Direct ByteBuffers的基础,尤其是MappedByteBuffers.
  • 在某些情况下,访问文件的内存映射区域可能会导致操作系统级异常,即SIGBUS.典型的例子是:

    1. 在截断基础文件后访问内存映射缓冲区.
    2. 网络驱动器上的文件已映射到内存,并且在网络连接丢失后访问映射的缓冲区.
    3. 尝试写入映射到文件tmpfs系统上的文件的页面会导致内存不足(默认情况下,tmpfs空间限制为总RAM的50%).
  • HotSpot JVM无法事先有效地检测到这些问题.它编译Unsafe.getX / putX对简单内存访问指令的调用.检查内存区域是否有效的附加检查太昂贵了.

  • 相反,JVM处理SIGBUG信号.如果它在Unsafe调用中发现错误,它会发布InternalError到当前线程并继续执行.
  • IOException更合适,但JVM不能抛出它或任何其他异常,因为ByteBuffer公共契约不允许其get/put方法抛出任何异常.
  • 如果Unsafe在JIT编译的方法中内存访问失败,JVM不会立即抛出异常(同样,对于这样的热ByteBuffer API来说它太昂贵了).相反,它会异步发布 InternalError到当前线程.这意味着错误实际上会抛出最近的本机方法或最近的VM运行时调用.因此错误消息中的"最近"一词.

请参阅JDK-4454115注释,描述相关JDK错误的解决方案.


zee*_*zee 5

由于磁盘空间问题也可能会发生这种情况。