C コードから Java メソッドを呼び出しています。呼び出しが行われるたびに、AttachCurrentThread を呼び出し、呼び出しが行われた後に DetachCurrentThread を呼び出します。
これは正常に動作しますが、問題は、JNI を介したほぼすべての呼び出しによって引き起こされる過剰なガベージ コレクションが表示されることです。マイナー コレクションの VisualVM グラフは、基本的にすべて緑色です。ネイティブ コードから Java への呼び出し速度は、毎秒数百です。その呼び出し中に、おそらく GC の理由である Thread-34543、Thread-34544、Thread-34545 などのように、過剰な数の Java スレッドが作成されていることもわかります。各呼び出しは異なるスレッドを介して行われるようです。
誰もこれを見たことがありますか?
それに加えて、DetachCurrentThread を使用しない場合、GC はまったくありませんが、VisualVM のスレッド ビューには VM に接続された数百のスレッドが表示されます。任意のヒント?
JVM 設定
-Xms2048m -Xmx2048m -XX:MaxDirectMemorySize=256M -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom. sun.management.jmxremote.port=3333
プラットフォーム: Ubuntu 12.04 Linux 3.2.0-35-generic #55-Ubuntu SMP Wed Dec 5 17:42:16 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux
ジャワ:
OpenJDK ランタイム環境 (IcedTea6 1.11.5) (6b24-1.11.5-0ubuntu1~12.04.1) OpenJDK 64 ビット サーバー VM (ビルド 20.0-b12、混合モード)
更新 2013-03-30
私の問題は別の場所にあると思います。スレッドの ID を出力しましたが、私の JNI コードを呼び出しているスレッドはほとんどないようです。最後の実行では、13 のスレッドが表示されました。問題は、実行時に
if ((*vm)->GetEnv(vm, (void**)&env, JNI_VERSION_1_4) == JNI_OK)
return env;
else
return NULL;
現在のスレッドに関連付けられている JNIEnv* を取得するには、エラー コード -2 (JNI_EDETACHED) が表示されます。明確にするために、私は DetachCurrentThread をまったく呼び出しません。これらのスレッドがネイティブ ライブラリに戻ってくることを期待しているためです。その場合、ネイティブ スレッドを再度アタッチすると、JVM で過剰な Thread オブジェクトが作成される可能性があります。最終実行ショー
29 [478e](get_env) Thread 2633996032 has env: (nil), err was: -2
47 [478e](get_env) Thread 2642388736 has env: (nil), err was: -2
32 [478e](get_env) Thread 2650781440 has env: (nil), err was: -2
31 [478e](get_env) Thread 2659174144 has env: (nil), err was: -2
37 [478e](get_env) Thread 2667566848 has env: (nil), err was: -2
30 [478e](get_env) Thread 2675959552 has env: (nil), err was: -2
32 [478e](get_env) Thread 2684352256 has env: (nil), err was: -2
33 [478e](get_env) Thread 2760873728 has env: (nil), err was: -2
33 [478e](get_env) Thread 2769266432 has env: (nil), err was: -2
37 [478e](get_env) Thread 2777659136 has env: (nil), err was: -2
36 [478e](get_env) Thread 2786051840 has env: (nil), err was: -2
31 [478e](get_env) Thread 2794444544 has env: (nil), err was: -2
52 [478e](get_env) Thread 3707176704 has env: (nil), err was: -2
ここで、最初の列は、接続されたスレッドに有効な環境が関連付けられていない呼び出しの数です。なぜそれが起こっているのですか?