web-dev-qa-db-ja.com

Javaの共有メモリの概念

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

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

私が間違っている場合は私を訂正してください。また、2 Java progsがお互いに話すための最も速い方法は何ですか?.

22
emkrish

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

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

14
Aaron Digulla

それを行うには少なくとも2つの方法があります RAMドライブ または Apache APR

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

23

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

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

理論的には、私が理解しているように、メモリマップファイルは実際には共有メモリセグメントによってサポートされます(これらは単なるファイルハンドルだと思います)が、Java JNIなし。

9
Cowan

Peter Lawreyの Java Chronicle プロジェクトは一見の価値があります。

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

9

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

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

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

7
Will

私が考えることができるいくつかの同等のテクノロジーがあります:

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

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

4
Nick Holt

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

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

2
rdalmeida

MappedBus( http://github.com/caplogic/mappedbus )は、githubに追加したライブラリであり、IPC複数(2つ以上)= Javaメッセージパッシングによるプロセス/ JVM。

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

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

1
MikaelJ

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

また、MappedByteBufferを使用しますが、データを永続化せず、Socket/ServerSocketのドロップイン置換として使用することを意図しています。

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

1
pcdv

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

0
Peter Schaeffer