2017-04-25 2 views
0

JVMは、オブジェクトのサイズに基づいて、Javaでnewキーワードを使用して作成されたオブジェクトにヒープメモリを割り当てます。 メモリ割り当ては内部的にどのように機能しますか。 JVMは次に大きな十分な空きブロックへのポインタを保持し、それを返すか、Cのmallocが内部でbrk()を呼び出すように、システムコールを通してメモリ割り当ての責任をOSに委譲しますか?Javaの新しいキーワード内部

+1

これはJRE実装に依存します。 – SLaks

+1

このロジックは、各JVM実装の内部にあります。 – dasblinkenlight

+0

あなたはこれで深すぎると思います。効果的であるためには、その知識は必要ありません。ウサギの穴を掘り下げることができます。 – solstinger

答えて

0

これはJVMに依存し、実装の詳細です。しかし、それは通常TLAB - スレッドローカル割り当てバッファを介して行われます。それより速い場合はmallocです。これは単純なポインタバンプです。それは非常に簡単な説明です。

0

正規のJava実装では、メモリ割り当ての世代戦略を使用します。

https://docs.oracle.com/cd/E13150_01/jrockit_jvm/jrockit/geninfo/diagnos/memman.html#wp1089132 http://www.oracle.com/technetwork/java/javase/memorymanagement-whitepaper-150215.pdf

オブジェクトは、「世代」と呼ばれる2つの領域に分割されている「ヒープ」メモリに割り当てられています。さらに「エデン」(「保育園」)と「生存スペース」に分かれている「若い世代」の領域があります。若い世代ではなく、本質的にすべてのヒープからなる、「古い」または「テナント化された」世代領域もあります。

通常、オブジェクトはEdenで最初に割り当てられます。エデンにとって大きすぎる「大きな」オブジェクトは、テニュア世代に入ります。

Edenがいっぱいになると、プログラム内の参照によってまだ到達可能なすべての「生きている」オブジェクトが最初の生き残り空間にコピーされ、Edenが消去され、空きEden空間へのポインタがスペースの始まり。

オブジェクトの割り当ては、単に新しいオブジェクトのアドレスとしてEdenの現在の "top"を指定することであり、オブジェクトのサイズだけ空きEdenメモリへのポインタが増えます。これは現代のコンピュータでは10 nsのようなものです。個々のオブジェクトは決して解放されないので、「フリー」に相当するものはありません。ヒープのセクション全体が単に消去され、フリーエリアポインタがリセットされます。 最初の生き残りスペースがいっぱいになると、JVMはライブオブジェクトとEdenをすべて他の生存スペースにコピーします。 Edenと最初の生き残り空間が消去され、ポインタがリセットされます。もう一方の生き残り空間は「最初」になり、古いものは「秒」になり、プロセスが繰り返されます。

死んだオブジェクトが追跡またはマークされず、よく書き込まれたプログラムでは、ほとんどが長く生きていない比較的小さなオブジェクトが多い傾向があるため、非常に高速です。

オブジェクトが長生きすると、オブジェクトは若い世代から期限が切れた世代に「昇進」しますが、これは低速のアルゴリズムを使用する頻度が低くなります。テニュアードオブジェクトは、若い世代よりも素早く死ぬ傾向があり、そうすると、その空間はちょうど中間のどこかの自由空間の「穴」になります。旧世代のガベージコレクションでは、通常、ライブオブジェクトを隣り合わせに移動して、空きメモリのブロックをより大きなブロックに統合します。

これは表面のちょっとした傷です。勉強することがもっとあります。

関連する問題