3

私のアプリケーションは2つの部分で構成されています -

Java でのいくつかの GUI ロジック。ネイティブ コード(主に Delphi) - GUI 実装自体。

Java は、ウィンドウのオープンやユーザー入力イベントへの応答などの簡単な操作にネイティブ コードを使用します。実装は JNI を介して行われます。

両側を異なるプロセスに分割することに興味があります-GUIをハングアップせずにそれらの間でIPCを実装する最良の方法は何ですか? 私は TCP ソケットまたは共有メモリに傾倒していますが、これに飛び込む前に、何らかの意見を聞きたいと思っています。パフォーマンスと簡単な実装が私の主な関心事です。

前もって感謝します。

4

3 に答える 3

3

問題がメモリ消費に関するものである場合

RAMが不足している場合(コメントで示唆されているように、主な質問にこれを書いたほうがよいでしょう。詳細を入力すればするほど、より良い答えが得られます)。

Java と Delphi を混在させているのはなぜですか? Java は、一般的なタスクでのメモリ消費量が多く、内部 GC が多いため、1 GB を超えるメモリを処理する候補にはおそらく適していません。JVM を 64 ビットで実行したとしても、新しいスケーリングの問題に直面することになります。Java で巨大なメモリを処理するには、非常に特殊なコードを記述する必要があります。

公平を期すために言えば、問題は Delphi に起因するのではなく、Java のメモリ消費に起因します。したがって、私見では、データレイヤーをネイティブコードでより適切にコーディングする必要があります。Java は潜在的に問題を増やしています。

次のいずれかを実行できます。

  • Free Pascal Compilerを使用して、 Delphi コードから 64 ビット ライブラリをコンパイルし、メインの 32 ビット Delphi アプリケーションから、またはメモリ マップ ファイルを bridge としてJNI を使用して Java から呼び出します。
  • データへのアクセス方法を変更します。一度にすべてのギガバイトのデータを取得する必要はないでしょう。ディスクに配置してから、RAMに残るインデックスを介してアクセスできます。Delphi を使用する場合は、独自のファイル処理を使用するか (ストレージとインデックス付きアクセスにBigTable ライブラリのようなものを使用できます)、データベースを使用する必要があります ( SQlite3 でさえ、その制限は約 140 テラバイトであるため、 GB のデータを処理できます)。 、データのみを取得するための SQL の機能を備えています)。
  • 本当に Java にとどまる必要がある場合は、プレーンなメモリ内構造の代わりに DB を使用できます。Java からの SQLite、または純粋な Java DB を使用できます。メモリ消費量を削減できると思います。

主なアプローチは、必要なものだけをメモリに保持し、Map/Reduce アルゴリズムまたはある種のインデックスを操作することです。

問題が Java と Delphi の間で GUI が混在している場合

私の実験では、JNI は独自のスレッドを使用する傾向があり、VCL はすべてのプロセスがメイン スレッドで実行されることを想定しているため、これは難しい可能性があります。

したがって、次のいずれかを実行できます。

  1. Delphi メソッドをいくつか作成し、JNI から呼び出されたときに VCL Synchronize メソッドを実行して画面を更新します。
  2. Windows GDI メッセージ通信に依存します。つまり、Delphi コードで独自の WM_USER* ハンドラを作成し、低レベルの PostMessage または SendMessage API を送信するだけで、Java コードから画面コンテンツを更新します。設計上、これはスレッドセーフになります。
  3. ステートレスなアプローチを使用する: 私はとても気に入っています。HTTP と同様に、ユーザー インターフェースはクライアントとして機能し、定期的にデータ レイヤー (サーバーとして機能) に更新されたデータを要求します。このプロセスはすべてメインスレッドに残り、タイマーを介して簡単に行うことができます。タイマーを使用すると、リフレッシュごとに 500 ミリ秒で十分であり、メイン アプリケーションは反応し続けます。

すべての場合において...

IPC の場合、メモリ マップ ファイルはソケットよりも高速ですが、少量のデータを処理する場合は GDI メッセージが理想的です。ソケットは良い候補であり、ローカル マシンでも高速です。メモリ マップ ファイルに関する小さなオーバーヘッドは、送信されるデータ量がほんの数 KB (たとえば最大 1 MB) の場合は目立ちません。また、アプリケーションのライト クライアント バージョンを作成する必要がある場合でも、それは機能します。

于 2011-06-20T06:27:21.843 に答える
1

回答に対する質問は、要件によって異なります (アプリケーションをこのように分割する十分な理由があると仮定します)。

「些細な」タスクを実行する必要がある場合、つまりデータ転送をあまり必要としない場合は、おそらくソケットを使用することをお勧めします。それにもかかわらず、バイトオーダーを尊重するなど、プロトコルを作成する必要があります。また、データを送信すると、GUI の応答が遅くなることにも注意してください。

大量のデータを転送する必要がある場合は、共有メモリを使用するとパフォーマンスが向上する可能性があります。ここでは、tcp の実装 (例: 送信/受信バッファ) によって行われる簿記を自分で行う必要があることに注意してください。これを使用すると、プロトコルが必要になるという問題はさらに悪化します。

于 2011-06-19T22:08:11.060 に答える
0

シンプルな実装が必要な場合は、アプリケーションを 2 つのプロセスに分割しないでください。パフォーマンスに関しては、これは問題ではありませんが、単一のアプリケーションで必要とされる以上の複雑さの順序を追加しています。このアーキテクチャで同じ機能を提供するためにかかる時間と労力を克服するには、アプリケーションを複数のプロセスに分割する十分な理由が必要です。

于 2011-06-19T23:59:07.193 に答える