How JVM ensures thread safety of memory allocation for a new object

后端 未结 2 1001
鱼传尺愫
鱼传尺愫 2020-12-25 15:00

Let\'s assume this is about to happen in a true parallel environment, one VM, at the same time:

// Thread 1:
  new Cat()

// Thread 2:
  new Dog()

// Thread         


        
相关标签:
2条回答
  • 2020-12-25 15:08

    I've briefly described the allocation procedure in HotSpot JVM in this answer.
    The way how an object is allocated depends on the area of the heap where it is allocated.

    1. TLAB. The fastest and the most frequent way.

    TLABs are the areas in Eden reserved for thread-local allocations. Each thread may create many TLABs: as soon as one gets filled, a new TLAB is created using the technique described in #2. I.e. creating of a new TLAB is something like allocating a large metaobject directly in Eden.

    Each Java thread has two pointers: tlab_top and tlab_limit. An allocation in TLAB is just a pointer increment. No synchronization is needed since the pointers are thread-local.

    if (tlab_top + object_size <= tlab_limit) {
        new_object_address = tlab_top;
        tlab_top += object_size;
    }
    

    -XX:+UseTLAB is enabled by default. If turn it off, the objects will be allocated in Eden as described below.

    2. Allocation in Eden (Young Generation).

    If there is not enough space in TLAB for a new object, either a new TLAB is created or the object is allocated directly in Eden (depending on TLAB waste limit and other ergonomics parameters).

    Allocation in Eden is similar to allocation in TLAB. There are also two pointers: eden_top and eden_end, they are global for the whole JVM. The allocation is also a pointer increment, but atomic operations are used since the Eden space is shared between all threads. Thread-safety is achieved by using architecture-specific atomic instructions: CAS (e.g. LOCK CMPXCHG on x86) or LL/SC (on ARM).

    3. Allocation in Old Generation.

    This depends on GC algorithm, e.g. CMS uses free lists. Allocation in Old Generation is typically performed only by Garbage Collector itself, so it knows how to synchronize its own threads (generally with the mix of allocation buffers, lock-free atomic operations and mutexes).

    0 讨论(0)
  • 2020-12-25 15:18

    This isn't specified in the Java specification. This means each JVM can do it however it wants to as long as it works and follows Java's memory guarantees.

    A good guess on how this works with a moving GC, would be each thread gets its own allocation zone. Where it does a simple pointer increase when allocating objects. Very simple and very quick allocation with no locking. When that is full either it gets a new allocation zone allocated to it, or the GC moves all live objects to a continuous part of the heap and returns the now empty zones back to each thread. I am not sure if this is how it is actually implemented in any JVM, and it would be complicated with GC synchronization.

    0 讨论(0)
提交回复
热议问题