2009-07-24 10 views
8

Javaが約12のマシン命令でオブジェクトのメモリを割り当てることができると私はどこか読んでいます。それは私のためにかなり印象的です。私が知る限り、JVMが使うトリックの1つは、メモリをあらかじめ割り当てておくことです。これはオペレーティングシステムへの要求の数を最小限に抑えるのに役立ちますが、これはかなり高価です。しかし、CASの場合でも、現代のプロセッサでは最大150サイクルのコストがかかることがあります。Java非ブロッキングメモリ割り当て

だから、誰でもJavaでのメモリ割り当ての実際のコストを説明することができ、割り当てを高速化するためにJVMが使うトリックはどれですか?

+0

ibm.com/developerworksに原料の束を持っていました。ほとんどの場合、既に持っているものを再利用しています。 –

答えて

17

は、JVMの各スレッドのためのメモリ領域を事前に割り当てます。

このすべては、ここでより詳細に説明します。 スレッドがメモリを割り当てる必要がある場合、その領域内で「ポインタ割り当てをバンプ」を使用します。 (「フリー・ポインタ」がアドレス10を指し、割り当てられるオブジェクトがサイズ50である場合、フリー・ポインタを60にバンプするだけで、オブジェクトに対して10と59の間のメモリを使用できることをスレッドに伝える) 。

+0

ありがとうございました。それは私が探しているものですが、それについてGoogleに尋ねる方法を知らなかった。 :)しかし興味深いのは...私がTLAについて見つけた唯一の言葉は、Oracle JRock JVM(フラグ-XXtlaSize)です。この機能はSun JVMにありますか? –

+1

Sunの用語はスレッドローカル割り当てバッファです。トランスレートルックアサイドバッファ(IBMを責める)のTLA標準であり、ハードウェアキャッシュマップを参照します。 –

+1

あなた、私は情報を見つけました。ありがとう。 Btw、翻訳ルックアサイドバッファはTLBのように省略されていると思います:) http://ja.wikipedia.org/wiki/Translation_lookaside_buffer –

2

最高のトリックは世代別ガベージコレクタです。これにより、ヒープが断片化されないようにするため、メモリを割り当てると、空き領域へのポインタが増え、古い値が返されます。メモリがなくなると、ガベージコレクションのコピーオブジェクトが作成され、この方法で新しい未断片化ヒープが作成されます。

ポインタが空きメモリに同期する必要があるため、スレッドを増やすと、チャンクがあらかじめ割り当てられます。したがって、スレッドはロックなしで新しいメモリを割り当てることができます。 (TLAまたはローカル・エリア・スレッド)http://java.sun.com/javase/technologies/hotspot/gc/gc_tuning_6.html

1

JVMのための単一のメモリアロケータはありません。 IIRCは、SunのJVMとIBMの管理対象メモリを正しく異ならせます。しかし、一般的にJVMが動作する方法は、最初に1つのメモリを割り当てることであり、このセグメントはプロセッサキャッシュに十分に小さくてすべてのアクセスが非常に高速になります。

アプリケーション内でオブジェクトを作成すると、オブジェクトはこのセグメント内からメモリを取得します。セグメント内のオブジェクトの割り当ては、単純にポインタ算術です。

最初は、新しく作成されたセグメントへのオフセットアドレスはゼロになります。割り当てられた最初のオブジェクトには、「アドレス」(実際にはセグメント内のオフセット)がゼロになります。あなたがオブジェクトを割り当てると、メモリマネージャはそのオブジェクトの大きさを知り、そのセグメント内に多くのスペースを割り振り(16バイト)、それを "オフセットアドレス"だけインクリメントします。算術。

日はここhttp://java.sun.com/j2se/reference/whitepapers/memorymanagement_whitepaper.pdf をホワイトペーパーを持っているとIBMは、典型的なJVMが唯一のヒープに余分なメモリを追加するためにOSを使用する