1

安全でないネイティブ コードを呼び出す必要がある Windows Java アプリケーションを作成しています。このコードが Java オブジェクトや JVM データ構造にアクセスできないようにする必要があります。そうしないと、JVM がクラッシュしたり、機密データがハッキングされたりする可能性があります。ご質問の前に、このネイティブ コードは以前に検証済みです。いくつかの API しか呼び出せず、特定の命令を使用できないため、VirtualProtect 自体や他のメモリ領域にアクセスして混乱させることはありません。

とにかく、私の最初の試みは、このコードを別のプロセス (サンドボックス) にラップし、IPC を使用して Java と対話することでした。Java 側で IPC を行う JNI DLL があります。基本的に、安全でないネイティブ コードを実行する必要があるたびに、Java アプリは JNI 関数を呼び出します。この関数は、自動リセット Windows イベントを使用してサンドボックスを起動し、完了を待ちます。サンドボックスは安全でないネイティブ コードを実行し、別の自動リセット Windows イベントを使用して JVM をウェイクアップします。それほど遅くなければ完璧です。

問題は、安全でないネイティブ コードに非常に高速な計算を実行し、Java から何百万回も呼び出すことができる関数が含まれている可能性があるため、呼び出しのオーバーヘッドを最小限に抑える必要があることです。ただし、JVM は Windows イベントでサンドボックスをウェイクアップし、サンドボックスが戻るとその逆になるため、このオーバーヘッドは非常に大きくなります。このプロセスは、安全でないネイティブ コードが JNI DLL にラップされているインプロセス (非 IPC) ソリューションの 8 倍の時間です (したがって、同じタイム スライスの同じスレッドで呼び出しが発生します)。

私の最初の推測では、JVM がサンドボックスをウェイクアップすると、Windows はサンドボックス スレッドを準備完了セットに置くだけなので、数ミリ秒後にのみ実行されます。サンドボックスが戻ったときも同じことが起こります。2 つの (コストがかかる可能性がある) コンテキスト スイッチはカウントされません。

ここのマイクロソフトのドキュメントには、次のように記載されています。

優先度の高いスレッドが実行可能になると、システムは優先度の低いスレッドの実行を停止し (タイム スライスの使用を終了させずに)、優先度の高いスレッドに完全なタイム スライスを割り当てます。

この理論をテストするために、THREAD_PRIORITY_TIME_CRITICAL をサンドボックス スレッドに割り当てました。いくつかの利益がありました。パフォーマンスは、インプロセス (非 IPC) ソリューションの時間の 8 倍から 5 倍になりました。しかし、もっと必要です。そうしないと、この Java アプリを本番環境に移行するための変更が行われない可能性があります。

次の 2 つの方法でお手伝いできます。

  • 強制的にコンテキストを切り替えたり、プロセス間プロシージャ コールを実行したりするなど、別のプロセスを起動するためのより高速な方法があれば教えてください。

  • 安全でないネイティブ コードをインプロセスで実行しているときに JVM を保護する方法を教えてください。Google Native Client がこれを行うと聞きましたが、このドキュメントしか見つかりませんでした。詳細をご存知の場合は、これがどのように実装されているかについての詳細情報へのリンクを提供してください。

4

1 に答える 1