私は4人のワーカースレッドが死なない私のWebサーバーにJVMを組み込みます。次のコードは、4人のワーカーのいずれかの内部の各http要求で実行されます。マルチスレッドJNIによって負荷下でsegfaultが発生する
// normally I would do URL routing here first, but this is just a JNI test now
jclass cls;
jmethodID method;
jobjectArray args;
jclass stringClass;
jstring jstr;
(*jvm)->AttachCurrentThread (jvm, &env, NULL);
cls = (*env)->FindClass(env, "HelloWorldClass");
method = (*env)->GetStaticMethodID(env, cls, "main", "([Ljava/lang/String;)V");
jstr = (*env)->NewStringUTF(env, "Hello world!");
stringClass = (*env)->FindClass(env, "java/lang/String");
args = (*env)->NewObjectArray(env, 1, stringClass, jstr);
(*env)->CallStaticVoidMethod(env, cls, method, args);
デバッガをステップスルーすると動作します。しかし、weighttpベンチマークで負荷をかけた場合、FindClass()
行またはCallSTaticVoidMethod()
行のいずれかにランダムにセグメンテーションが発生します。何が問題なの?私は多くのドキュメントを読んでいますが、私はここでどのようにロックしたり解放したりする必要があるのか分かりません。
これは、公式ドキュメントから引き継が、かなりの可能性である最も基本的なJNIコードです:私はグローバルスコープにJNIEnvの*を入れているようhttp://java.sun.com/docs/books/jni/html/invoke.html
もちろんグローバルにすると問題になります。すべてのスレッドは独自の値を必要とします。グローバルであれば、お互いの価値を使うことができます。 – EJP
ああ、グローバル変数はプロセス全体に対して一度しか存在しないからです。私は各スレッドに独自のコピーがあると私に言った脳の凍結を持っていました。 – Blub