Java で実行する場合new Object()
、jvm はロックレス アルゴリズムを使用してメモリを割り当てますか、それともロックする必要がありますか?
この場合に言及している JVM は Hotspot VM です。私がそれについて知っていることはほとんどありませんが、ポインターをインクリメントするだけでメモリを超高速に割り当てることができます。しかし、複数のスレッドの場合、そのインクリメントにはロックまたは CAS が必要ですか?
Java で実行する場合new Object()
、jvm はロックレス アルゴリズムを使用してメモリを割り当てますか、それともロックする必要がありますか?
この場合に言及している JVM は Hotspot VM です。私がそれについて知っていることはほとんどありませんが、ポインターをインクリメントするだけでメモリを超高速に割り当てることができます。しかし、複数のスレッドの場合、そのインクリメントにはロックまたは CAS が必要ですか?
前述のように、デフォルトでは tlab を使用します。この用語集では、動作について次のように説明されています。
TLAB
Thread-local allocation buffer. Used to allocate heap space quickly without synchronization. Compiled code has a "fast path" of a few instructions which tries to bump a high-water mark in the current thread's TLAB, successfully allocating an object if the bumped mark falls before a TLAB-specific limit address.
このブログのサイジングの詳細と、このブログで必要なすべての詳細。
つまり、TLAB がいっぱいでない限りスレッド ローカルです。その場合、共有プールをヒットする必要があり、これは CAS 操作です。
もう 1 つの複雑な要因は、カード マーキングでの誤った共有を説明するこのバグである可能性があります。これは、それ自体はロックではありませんが、パフォーマンスを低下させます (これがロックについて質問している理由である場合)。ただし、これはjava7で修正されているようです。
それは依存します:)-XX:+UseTLAB
オプション(Peterが指摘したSun / Oracle JVMのデフォルト)を使用すると、スレッドローカルヒープにより「ハッピーパス」で競合がなくなると思います。もちろん、十分なスペースがないためにガベージコレクションが必要な場合は、さまざまな実装があり、すべてが非常に複雑な並列 GC などの領域に入ります...そしてもちろん、これは常に進行しています。
「単一ヒープ」モデルであっても、割り当てが高度に最適化されることを期待します。通常の意味でのロックの取得ではなく、可能であればアトミック インクリメントを実行します。詳細を知っているとは言えませんが。