1

Javaは複数のスレッドを同時に実行できると言われています。また、オブジェクトの作成は安価であるため、オブジェクトを再利用するために新しいオブジェクトを作成することを常に選択する必要があります。しかし、私の知る限り、オブジェクトはグローバルスコープで作成されます(GCの対象になる)。スレッドがオブジェクトを作成するときに並列処理が停止するのは不思議です。JVMパラレルオブジェクト作成のパフォーマンス

AFAIKでは、アンマネージ言語は、スレッドが独立して実行されるようにスレッドスタックにオブジェクトを作成します。サブプログラムスコープを終了すると、それらはすべて削除されます。つまり、オブジェクトをグローバルリストに追加して、マシンをGCに後で停止させる必要はありません。 JavaでInt/Stringのような不変のオブジェクトでも同じことができます。なぜなら、GCがクリーンアップを必要とする循環依存を作成する他のオブジェクトを参照できないからです。しかし、afaik、何もJavaのプロシージャの終了でクリーンアップされていません。

+0

質問はまだ私にはっきりしていません。あなたが基本的に求めていることについてもう少し説明できますか? – pbajpai21

答えて

2

TLAB(Thread Local Allocation Buffer)のため、小さなオブジェクトの割り当てはほとんどの場合非常に安価です。すべての単一のスレッドには、TLABと呼ばれるスレッドローカル割り当て用に予約されたEdenの特別な領域があります。

したがって、前回の書き込み時に新しいTLABを割り当てる場合にのみ同期が必要です。この同期はCAS操作であるため、非常に高速です。

 Eden      Survivor 1/2 
------------------------------------------------- 
| T |  | T |    ||  |  | 
| L |  | L |    ||  |  | 
| A |  | A |    ||  |  | 
| B |  | B |    ||  |  | 
| |  | |    ||  |  | 
| 1 |  | 2 |    ||  |  | 
------------------------------------------------- 
^  ^
    |   | 
    reserved for|thread-1 allocations 
       | 
       | 
       reserved for thread-2 allocations 

さらに、最適化によっては、コンパイルされたコード(エスケープ解析とスカラー置換)の割り当てを避けることができます。いくつかのシナリオでは、コンパイラはオブジェクトのすべてのフィールドをスタックに配置することによって割り当てをなくすことができます。

+1

スレッドがTLAB外のヒープ変数を変更しない限り、他のスレッドがそのTLAB内の新しく作成されたオブジェクトへの参照を持つことは不可能です。そして、JVMはそれを正確に追跡して、ローカルまたはマイナーなコレクションを有効にします。これは、JVM全体を停止する必要はありません(質問の2番目の段落に対処するため)。 – Holger

関連する問題