【问题标题】:JNI is crashing the java in windows 7JNI 正在使 Windows 7 中的 java 崩溃
【发布时间】:2016-04-19 07:44:44
【问题描述】:

我正在将代码从 linux 移植到 windows,因为 Java 不支持 Linux 共享内存段。因此,我们使用 Java Native Interface (JNI) 来访问共享内存。它在 linux 平台上运行良好。

shmget 的代码:

JNIEXPORT jint JNICALL Java_emulatorinterface_communication_shm_SharedMem_shmget
(JNIEnv * env, jobject jobj, jint COUNT,jint MaxNumJavaThreads,jint EmuThreadsPerJavaThread,
        jlong coremap, jint pid) {

    uint64_t mask = coremap;

    int size;//=sizeof(packet)*(COUNT+5)*MaxNumJavaThreads*EmuThreadsPerJavaThread;

    char str[50];
    int ptr;

#ifdef _WIN32
    HANDLE hMapFile;
#endif
    printf("hello");
    size=sizeof(packet)*(COUNT+5)*MaxNumJavaThreads*EmuThreadsPerJavaThread;
    /*if (sched_setaffinity(0, sizeof(mask), (cpu_set_t *)&mask) <0) {
        perror("sched_setaffinity");
    }*/


    //set the global variables
    gCOUNT = COUNT;
    gMaxNumJavaThreads = MaxNumJavaThreads;
    gEmuThreadsPerJavaThread = EmuThreadsPerJavaThread;

    //size1 is the number of packets needed in the segment.

#ifdef _WIN32

    _itoa(pid,str,10);


    hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE,
        NULL, PAGE_READWRITE,
        0,32, str);

    if (hMapFile == NULL)
    {

         exit(1);
    }
    CloseHandle(hMapFile);

    hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE,
        NULL, PAGE_READWRITE,
        0,size, str);

    if (hMapFile == NULL)
    {
        printf("Unable to create a shared mem file.");
        exit(1);
    }
    if (hMapFile < 0)
    {
        return (-1);
    }

    /*
    if((hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE,
        NULL, PAGE_READWRITE,
        0,size, str))<0)
    {
        printf("error window %d\n",size);
        return (-1);
    }
    */
    ptr=*((int*)(hMapFile));

    return ptr;          ///////////////error in return type 
    #else

如果我尝试使用 JNI 中的任何其他函数,我的 java 崩溃。

错误

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x000007feedf911be, pid=4696, tid=4216
#
# JRE version: Java(TM) SE Runtime Environment (8.0_77-b03) (build 1.8.0_77-b03)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.77-b03 mixed mode windows-amd64 compressed oops)
# Problematic frame:
# C  [JNIShm.dll+0x11be]
#
# Failed to write core dump. Minidumps are not enabled by default on client versions of Windows
#
# An error report file with more information is saved as:
# D:\workspace\tejasMinor\hs_err_pid4696.log
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.java.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#

谁能指出问题出在哪里?

【问题讨论】:

  • 我的回答对你有帮助吗?

标签: java windows-7 java-native-interface


【解决方案1】:

您不能将HANDLE 取消引用到文件映射对象。只需让你函数返回句柄,如下所示:

return (int)hMapFile;

在 64 位 Windows(使用 64 位 JRE/JNI)上,HANDLE 类型是 64 位宽,但只有低 32 位是有效的,所以没关系。

旁注:

  1. 不要使用hMapFile &lt; 0。如果 API 失败,返回值为NULL
  2. 您确定需要先尝试一个 32 字节的文件,然后再关闭它吗?为什么?
  3. 您可能需要致电 GetLastError 并针对 ERROR_ALREADY_EXISTS 测试结果(如果您希望能够检测到这种情况)

【讨论】:

  • 感谢您的回复。我做了必要的更改。现在我在循环中的前几次收到 ERROR_ALREADY_EXISTS,后来它给出了正确的值。为什么会发生这种情况?我该如何纠正它?
  • @kunal 这是另一个问题。我的回答对您的崩溃有帮助吗?当CreateFileMapping 说内存映射命名对象已经存在时,这意味着...如果您想打开一个已经存在的对象,请使用OpenFileMapping。另外:为什么要谈论循环?!?
  • 是的,它有帮助。谢谢。好的,我将尝试使用 OpenFileMapping。我的程序需要循环运行它,我后来添加了 getError 逻辑以找出错误。但我没有'不明白为什么它说文件存在几次迭代然后成功创建了对象。为什么会这样?
  • @Kunal 感谢您接受答案。当CreateFileMapping 说文件已经存在时,这并不是真正的错误。返回的句柄是有效的。这只是表明共享内存已经创建(使用该名称)和/或尚未“关闭”。内存将一直存在到最后一个HANDLE它没有“关闭”。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-07
  • 2012-07-16
  • 2011-04-09
  • 2011-08-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多