jni-wrapper在Windows上崩溃了JVM

时间:2017-08-31 07:49:53

标签: c java-native-interface free

我编写了一个JNI-Wrapper但直到今天才在Linux上使用它。 现在我为windows编译它,并且JVM在这些本机方法中崩溃: 如果我删除ReleaseStringUTFCharsfree调用它也适用于Windows,但有趣的是,为什么这适用于Linux但不适用于Windows?(我使用Windows 10-64bit)。根据我的经验,这些调用是强制性的,在我正确发布之前,在开始时有一些内存泄漏(在linux上)

void onMessageReceived(char* topic, char* timestamp, char* id, char* value) {
JNIEnv * g_env;
int getEnvStat = (*g_vm)->GetEnv(g_vm, (void **) &g_env, JNI_VERSION_1_8);
if (getEnvStat == JNI_EDETACHED) {
    if ((*g_vm)->AttachCurrentThread(g_vm, (void **) &g_env, NULL) != 0) {
        puts("Failed to attach");
        fflush(stdout);
    }
}

if (methodHandleMessage) {
} else {
    jclass clazz = (*g_env)->GetObjectClass(g_env, store_callback);
    methodHandleMessage = (*g_env)->GetMethodID(g_env, clazz, "handleMessage", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
}
jstring j_topic = (*g_env)->NewStringUTF(g_env, topic);
jstring j_timestamp = (*g_env)->NewStringUTF(g_env, timestamp);
jstring j_value = (*g_env)->NewStringUTF(g_env, value);
jstring j_id = (*g_env)->NewStringUTF(g_env, id);


(*g_env)->CallVoidMethod(g_env, store_callback, methodHandleMessage, j_topic, j_timestamp, j_id, j_value);

//HERE IS THE PROBLEM:
(*g_env)->ReleaseStringUTFChars(g_env, j_topic, topic);
(*g_env)->ReleaseStringUTFChars(g_env, j_timestamp, timestamp);
(*g_env)->ReleaseStringUTFChars(g_env, j_value, value);
(*g_env)->ReleaseStringUTFChars(g_env, j_id, id);
//

(*g_vm)->DetachCurrentThread(g_vm);
}

void rep_actor(zsock_t *pipe, void *args) {
zsock_signal(pipe, 0);
while (!zsys_interrupted) {
    char* timestamp;
    char* sender;
    char* command;
    char* message;

    zsock_recv(reply, "ssss", &timestamp, &sender, &command, &message);

    char* result = onRequestReceived(timestamp, sender, command, message);
    zsock_send(reply, "s", result);

//HERE IS THE PROBLEM:

    free(timestamp);
    free(sender);
    free(command);
    free(message);
    free(result);
//

}
}

1 个答案:

答案 0 :(得分:1)

发生错误是因为您释放了两次内存。第一次 - 在ReleaseStringUTFChars()内调用onMessageReceived(),在onMessageReceived()之外调用free(),在每个释放的指针上调用env->New*()

重要
对于在java环境中创建的对象(调用// j_topic - it's a pointer for object inside of java heap // garbage collector will free this memory jstring j_topic = env->NewStringUTF(topic); 方法),您不需要手动释放内存。在你的情况下:

ReleaseStringUTFChars()

此处String的电话不适合。仅在使用GetStringUTFChars()从java // j_topic - string inside of java heap const char* native_str = env->GetStringUTFChars(j_topic, isCopy); // your logic for native_str array // informs the VM that the native code no longer needs access to native_str env->ReleaseStringUTFChars(j_topic, native_str); 创建本地字符串时使用:

GetStringUTFChars()

查看javadoc方法ReleaseStringUTFChars() let date = NSDate() var dateComponents = DateComponents() dateComponents.hour = -6 let calculatedDate = NSCalendar.current.date(byAdding: dateComponents, to: date as Date) let selectStatement = "SELECT nr from info where date > \(UInt((calculatedDate!.timeIntervalSince1970)) * 1000);" - 您应该只使用它们。