Object creation

When the Java virtual machine reaches a bytecode new instruction, it first checks to see if the instruction’s arguments locate a symbolic reference to a class in the constant pool, and to see if the symbolic reference represents a class that has been loaded, parsed, and initialized. If not, you must first perform the appropriate classloading process, which is discussed in chapter 7 of this book.

If memory in the Java heap is perfectly neat, all used memory is placed on one side, free memory is placed on the other, and a pointer is placed in the middle as an indicator of the dividing point. The allocated memory simply moves that pointer to free space by an equal distance to the size of the object. This allocation is called a “Bump The Pointer.” But if the memory in the Java heap is not neat, has been the use of memory and free memory staggered together, that is simply no way pointer collision, the virtual machine, you must maintain a list of records on which memory blocks are available, at the time of points with from the list to find a large enough space division to the object instance, And updates the records on the List, which is called a “Free List.”

To ensure atomicity of memory allocation on VMS, the CAS configuration fails and retry is used.

After the memory allocation is complete, the virtual machine must initialize the allocated memory space (but not the object header) to zero.

The Java virtual machine then sets up the Object as necessary, such as which class the Object is an instance of, how to find the metadata information about the class, the Object’s hashCode(which is actually deferred until the Object::hashCode() method is actually called), the Object’s GC generation age, and so on. This information is stored in the Object Header of the Object. The object header can be set differently depending on the VM running status, for example, whether biased locking is enabled. More on the contents of object headers later.

code

// Make sure the constant pool holds interpreted classes
    if(! constants->tag_at(index).is_unresolved_klass()) {// Ensure that klassOop and instanceKlassOop are asserted (this is covered in the next section)
      oop entry = (klassOop) *constants->obj_at_addr(index);
      assert(entry->is_klass(), "Should be resolved klass");
      klassOop k_entry = (klassOop) entry;
      assert(k_entry->klass_part()->oop_is_instance(), "Should be instanceKlass");
      instanceKlass* ik = (instanceKlass*) k_entry->klass_part();
      // Make sure that the object type has passed the initialization phase
      if ( ik->is_initialized() && ik->can_be_fastpath_allocated() ) {
        // Take the length of the object
        size_t obj_size = ik->size_helper();
        oop result = NULL;
        // Records whether all fields of the object need to be set to zerobool need_zero = ! ZeroTLAB;// Whether to allocate objects in TLAB
        if (UseTLAB) {
          result = (oop) THREAD->tlab().allocate(obj_size);
        }
        if (result == NULL) {
          need_zero = true;
          // Allocate objects directly in Eden
    retry:
          HeapWord* compare_to = *Universe::heap()->top_addr();
          HeapWord* new_top = compare_to + obj_size;
          // CMPXCHG is the CAS instruction in x86. This is a C++ method that allocates space in CAS mode. If concurrent space fails, retry it until it is successfully allocated
          if (new_top <= *Universe::heap()->end_addr()) {
            if (Atomic::cmpxchg_ptr(new_top, Universe::heap()->top_addr(), compare_to) != compare_to) {
              goto retry;
            }
            result = (oop) compare_to;
          }
        }
        if(result ! = NULL) {// Initialize the object with a zero value if necessary
          if (need_zero ) {
            HeapWord* to_zero = (HeapWord*) result + sizeof(oopDesc) / oopSize;
            obj_size -= sizeof(oopDesc) / oopSize;
            if (obj_size > 0 ) {
              memset(to_zero, 0, obj_size * HeapWordSize); }}// Set the object header according to whether biased locking is enabled
          if (UseBiasedLocking) {
            result->set_mark(ik->prototype_header());
          } else {
            result->set_mark(markOopDesc::prototype());
          }
          result->set_klass_gap(0);
          result->set_klass(k_entry);
          // Pushes the object reference onto the stack to proceed to the next instruction
          SET_STACK_OBJECT(result, 0);
          UPDATE_PC_AND_TOS_AND_CONTINUE(3.1); }}}Copy the code

Object memory layout

In the HotSpot virtual machine, the storage layout of objects in the heap memory can be divided into three parts: object headers, Instance Data, and Padding.

Object head

The object header contains two types of information. The first type is runtime data used to store the object itself, such as HashCode, GC generation age, lock status flags, locks held by threads, bias thread ids, bias timestamps, and so on.

The other part of the object header is the type pointer, the pointer to the object’s type metadata, which the Java virtual machine uses to determine which class the object is an instance of.

The instance data

That is, fields of various types defined in our program code, whether inherited from a parent class or defined in a subclass, must be recorded.

Alignment filling

It serves only as a placeholder. The size of any object must be an integer multiple of 8 bytes.

Object access location

Therefore, object access methods are also determined by virtual machines. The main access methods are handle and direct pointer.

Handle access

The biggest benefit of handle access is that Reference stores a stable handle address and only changes the instance data pointer in the handle when the object is moved (a very common behavior in garbage collection). Reference itself does not need to be modified.

A pointer to access

The biggest benefit of direct pointer access is that it is faster, it saves the time overhead of a pointer location.

Reference:

  • In-depth understanding of the Java virtual machine
  • In-memory structure of Java objects (HotSpot VIRTUAL Machine)