2017-08-31 5 views
1

私はJNI-Wrapperを書いていますが、今日までLinuxでのみ使用しています。 これをWindows用にコンパイルし、このネイティブメソッドでJVMがクラッシュする: ReleaseStringUTFCharsfreeという呼び出しを削除すると、Windowsでも動作しますが、Linuxでは動作しますがWindowsでは動作しないのはなぜですか? 10-64ビット)。私が正しくWindows上でjni-wrapperがJVMをクラッシュする

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

エラーがあなたのために空きメモリを二度起こるそれらを解放する前にこの呼び出しは必須です私の経験から、初めに(Linuxの場合)、いくつかのメモリリークを得ました。初めてReleaseStringUTFChars()onMessageReceived()の内側に、onMessageReceived()の外側に2番目に出すと、リリースされた各ポインタに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()のコールはここでは不適切です。あなたがGetStringUTFChars()を使用してJava Stringからネイティブ文字列作成する場合にのみ使用:メソッドGetStringUTFChars()ReleaseStringUTFChars()ためjavadoc

// 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); 

ルック - あなただけ一緒に彼らを使用する必要があります。

+0

ありがとうございます。私はメモリを2回解放するとクラッシュすることはありません – user2071938

関連する問題