22

AFAIK、Javaのメモリは、メモリがオブジェクトに動的に割り当てられるヒープに基づいており、共有メモリの概念はありません。

共有メモリの概念がない場合、Javaプログラム間の通信には時間がかかるはずです。Cでは、他の通信モードと比較して、共有メモリを介したプロセス間通信が高速です。

私が間違っている場合は私を訂正してください。また、2つのJavaプログラムが互いに通信するための最も速い方法は何ですか。

4

10 に答える 10

24

いくつかの方法:

ここここの詳細といくつかのパフォーマンス測定。

于 2011-09-15T22:08:42.333 に答える
13

共有メモリセグメントを作成するための公式APIがないため、2つのJavaプロセスが相互に通信できるように共有メモリを使用するには、ヘルパーライブラリ/DDLとJNIを使​​用する必要があります。

実際には、Javaはスレッドをサポートしているため、これが問題になることはめったにありません。そのため、同じJavaVMで2つの「プログラム」を実行できます。それらは同じヒープを共有するため、通信は瞬時に行われます。さらに、共有メモリセグメントに問題があるため、エラーが発生することはありません。

于 2009-09-29T09:39:49.203 に答える
9

JavaChronicleは一見の価値があります。Chronicle-QueueChronicle-Mapはどちらも共有メモリを使用します。

これらは、さまざまなオフヒープオプションとオンヒープオプションを比較するために私がしばらく前に行ったいくつかのテストです。

于 2012-03-16T18:42:47.290 に答える
8

注目すべきことの1つは、メモリマップトファイルの使用、Java NIOのFileChannelクラスなどの使用です(map()メソッドを参照)。これを非常にうまく使用して、同じマシン上のJavaプロセスとCネイティブプロセスの間で(この場合は一方向に)通信しました。

私はファイルシステムの専門家ではないことを認めますが(幸いなことにスタッフがいます!)、パフォーマンスは非常に高速です。事実上、ページキャッシュのセクションをファイルとして扱い、読み取りと書き込みを行っています。システムコールのオーバーヘッドなしで直接それを行います。保証と一貫性についてはよくわかりません。Javaには、変更をファイルに強制的に書き込むメソッドがあります。これは、変更が実際の基になるファイルに書き込まれることを意味します(場合によっては?通常?通常?通常?不明)。 (やや?非常に?非常に?)怠惰です。つまり、時間の一部は基本的に単なる共有メモリセグメントです。

理論的には、私が理解しているように、メモリマップトファイルは実際には共有メモリセグメントによってバックアップできます(ファイルハンドルにすぎないと思います)が、JNIなしでJavaでこれを行う方法を私は知りません。

于 2009-09-29T13:24:48.523 に答える
6

共有メモリは時々速いです。場合によってはそうではありません-CPUキャッシュを傷つけ、同期はしばしば苦痛です(そして、ミューテックスなどに依存する場合、パフォーマンスが大幅に低下する可能性があります)。

Barrelfishは、コアの数が増えるにつれて、メッセージパッシングを使用するIPCが実際には共有メモリよりも高速であることを示すオペレーティングシステムです(従来のX86アーキテクチャ、およびターゲットとしていたと思われるよりエキゾチックなNUMA NUCAのもの)。

したがって、共有メモリが高速であるという仮定は、特定のシナリオとターゲットハードウェアでテストする必要があります。最近の一般的な音の仮定ではありません!

于 2009-09-29T09:42:37.777 に答える
3

私が考えることができるいくつかの同等の技術があります:

  1. 数年前、JavaSpacesと呼ばれるテクノロジーがありましたが、それが実際に定着しているようには見えませんでした。私に言わせれば残念です。
  2. 現在、 CoherenceTangosolなどの分散キャッシュテクノロジーがあります。

残念ながら、どちらも共有メモリの速度は適切ではありませんが、同時アクセスなどの問題には対処します。

于 2009-09-29T09:54:30.140 に答える
2

これを行う最も簡単な方法は、2つのプロセスで同じメモリマップトファイルをインスタンス化することです。実際には、それらは同じオフヒープメモリスペースを共有します。このメモリの物理アドレスを取得して、sun.misc.Unsafeプリミティブの書き込み/読み取りに使用できます。putXXXVolatile/getXXXVolatileメソッドによる同時実行をサポートします。同じJVM内でIPCとスレッド間通信を簡単に提供するCoralQueueを見てください。

免責事項:私はCoralQueueの開発者の1人です。

于 2015-05-01T03:08:07.500 に答える
1

PeterLawreyのJavaChronicleと同様に、 Jocketを試すことができます。

また、MappedByteBufferを使用しますが、データを保持せず、Socket/ServerSocketのドロップイン置換として使用することを目的としています。

1kBのピンポンの往復遅延は約0.5マイクロ秒です。

于 2013-10-29T12:47:51.823 に答える
1

MappedBus(http://github.com/caplogic/mappedbus)は、メッセージパッシングによって複数(2つ以上)のJavaプロセス/JVM間のIPCを有効にするライブラリをgithubに追加しました。

トランスポートは、メモリマップトファイルまたは共有メモリのいずれかです。共有メモリで使用するには、githubページの例に従いますが、リーダー/ライターに「/ dev /shm/」の下のファイルを指定します。

これはオープンソースであり、実装についてはgithubページで詳しく説明されています。

于 2015-05-18T16:59:52.260 に答える
0

Cowanから提供された情報は正しいです。ただし、共有メモリでさえ、同時に複数のスレッド(および/またはプロセス)で常に同一であるように見えるとは限りません。主な根本的な理由は、Javaメモリモデル(ハードウェアメモリモデルに基づいて構築されている)です。複数のスレッドがJavaで直接マップされたByteBufferへの書き込みを確認できますか?を参照してください。主題の非常に有用な議論のために。

于 2013-10-24T17:06:50.780 に答える