来自JNI_CreateJavaVM(jvm.dll)的异常0xC0000005

时间:2016-03-27 17:14:13

标签: java visual-studio-2015 jvm java-native-interface

我正在使用以下C ++代码初始化Java VM。 JNI_CreateJavaVM会抛出0xC0000005异常,但如果忽略它就会成功。

  

' Jni.exe' (Win32):已加载' C:\ Tools \ Java \ Jdk8.77x86 \ jre \ bin \ zip.dll'。无法找到或打开PDB文件。

     

Jni.exe中0x02900282处抛出异常:0xC0000005:访问冲突读取位置0x00000000。

     

' Jni.exe' (Win32):已加载' C:\ Windows \ SysWOW64 \ shell32.dll'。无法找到或打开PDB文件。

我忘了设置或做某事或这是否正常'行为?

#include <array>
#include "jni.h"

int main( int argc, char const* args[])
{
    JavaVM* jvm;
    JNIEnv* env;

    std::array<JavaVMOption,1> options;
    options[0].optionString = "-Djava.class.path=C:/Users/Thomas/Documents/Visual Studio 2015/Projects/Jni/x64/Debug";
    options[0].extraInfo = nullptr;

    JavaVMInitArgs vm_args;
    vm_args.version = JNI_VERSION_1_8;
    vm_args.options = options.data();
    vm_args.nOptions = options.size();
    vm_args.ignoreUnrecognized = false;

    auto rc = JNI_CreateJavaVM( &jvm, reinterpret_cast<void**>(&env), &vm_args );
    if( rc == JNI_OK )
    {
        jvm->DestroyJavaVM();        
    }
}

对于Release和Debug以及x86和x64版本都会发生这种情况。

2 个答案:

答案 0 :(得分:13)

JVM主动使用OS信号(或Windows术语中的例外)用于其自身目的:

  • 用于隐式空指针检查和堆栈溢出检查;
  • 用于安全点轮询;
  • 用于远程内存屏障;

在JVM启动时也会有意生成SEGV(或异常0xC0000005)以验证某些CPU / OS功能。某些操作系统或管理程序有一个错误,即AVX寄存器在信号处理后没有恢复。因此,JVM需要检查是否是(the source)的情况。因此它通过写入零地址然后处理它来生成异常。

这就是你的情况。是的,这是正常的。

答案 1 :(得分:1)

这很正常,就像@apangin说的那样。如果要在Visual Studio(2017)中关闭所有0xC0000005异常,则可以执行以下操作:

  1. 例外设置- Ctrl + Alt + E
  2. 从Win32例外中删除“ 0xc0000005访问冲突”中的刻度