1

JNI を利用するテキスト/VoIP プログラムの C++/ネイティブ側を作成しています。現在、C++ 側には、Java コードによって定期的に呼び出される可能性のある関数が 3 つあります。関数が呼び出される頻度は、ユーザーがテキスト メッセージを送受信する頻度と、友人がプレゼンス/ステータスを変更する際にどれだけアクティブであるかによって異なります。3 つの関数はそれぞれ以下の疑似コードに従いますが、関数内の何かを「グローバル化」することが賢明かどうか (または可能かどうかさえ) わかりません。

JNIEnv *env;
if (jvm_->GetEnv((void**) &env, JNI_VERSION_1_6) < 0)
{
[print error and return]
}

jclass stringclass = env->FindClass("java/lang/String"); // Same for all 3
jstring passinfo = env->NewStringUTF([str-info-to-pass]); // Different for all 3
jclass cls = env->FindClass([directory to calling Java function class]); // Same for all 3
[check if cls found, print error if not found and return]

jmethodID methID = env->GetStatisMethodID([arguments for the function]); // Different for all 3
[check if methID found, print error if not found and return]

jobjectArray args = env->NewObjectArray([arguments to build argument structure being passed to function]);
[call Java function, passing right arguments]

私は、jclass stringclass、jclass cls、および JNIEnv *env を関数から移動し、JNI_OnLoad 関数呼び出し中に設定されたグローバルにする必要がある/できると考えていました。これは可能/推奨ですか?これらの値は、OnLoad 関数とこれらの関数で何らかの違いがありますか? それらをグローバルとしてインスタンス化し、関数呼び出しで毎回設定する必要がありますか? そして、これらのいずれかを実行すると、パフォーマンスが大幅に向上しますか?

4

2 に答える 2

2

可能です、はい。賢い、それは依存します。「顕著な量」とは何かを自分で定義します。予想される JNI 呼び出しの頻度はどれくらいですか? 1 秒あたり 10 回以上の呼び出しから始まるキャッシングの測定可能な影響を確認できると思います。それはケースですか?とにかく、私の個人的な経験では、適切に行われたキャッシュはコードをクリーンアップし、コードを短くして読みやすくします。だから私はとにかくアドバイスをします。

のキャッシュ結果FindClass、はい、絶対に。一般に、再利用可能で「静的」なもの、つまりシンボリック名で検索しているもの - これは、単にキャッシュされたポインターを使用するのとは対照的に、シンボリック検索のペナルティをもたらします。Liang JNI の書籍では、フィールド ID とメソッド ID についても説明されているため、GetStaticMethodID適用されます。の結果を直接キャッシュできるjmethodIDという意味で単純です。それ以降の呼び出しに対して有効です。ローカル参照を返すものGet(Static)MethodIDとは異なり、有効なキャッシング (および実際に永続化する)のためには、そこから作成し、必要に応じて削除する必要があります。JNI_OnLoad チュートリアルには、優れた包括的な例があります。FindClassjmethodIDNewGlobalRef. 一方、JNIEnv をキャッシュしても意味がありません。JNI 呼び出しごとに再度取得します。キャッシュした JNIEnv は、キャッシュしたスレッドとは別のスレッドから JNI メソッドを呼び出した場合も無効になります。

于 2012-08-15T17:54:50.310 に答える
0

パフォーマンスについて心配する必要はありません。現在、ネイティブ コーデックを使用する voip クライアントを開発しています。これは、すべての rtp パケットに対して JNI が呼び出され (エンコードとデコードの両方のため、20 ミリ秒ごとに 2 回)、各呼び出しで JNIEnv も渡すことを意味します。この変数は単なるポインターです。JNI 呼び出しで消費される CPU 使用率は、ローエンド デバイスで 1% を下回っています。

于 2014-01-29T13:07:23.070 に答える