Personal blog

www.milovetingting.cn

Analyze the object creation process

preface

When we create an object, we might create it like this:

Object object = new Object();
Copy the code

It seems to be a very simple process, so what are the relevant knowledge points behind this new operation that we need to master? This paper will introduce them.

Object creation process

Classes are loaded into memory by the JVM using the parent delegate mechanism. The details of the parent delegate mechanism are not expanded here. Class loading involves the following processes:

loading

Load Class information into memory, which can be read from a Class file, a Zip package, or at run time through a dynamic proxy.

The connection

validation

Verify that the byte stream in the Class file contains the information required by the virtual machine.

To prepare

Allocates memory for member variables of a class object and sets the initial value of the class’s member variables.

parsing

The virtual machine replaces symbolic references in the constant pool with direct references.

Initialize the

Execute the init method of the class constructor.

use

Object usage process.

uninstall

Unload when all objects of the class have been released.

Create a way

The object creation method can be directly created by using the new method, but generally, to facilitate the realization of global uniqueness of the object, the singleton is implemented.

Singletons are simple to implement, including the following:

  • The hungry type

  • LanHanShi

  • Static inner class

  • The enumeration

The hungry type

private static Singleton instance = new Singleton();

    private Singleton(a) {}public Singleton getInstance(a) {
        return instance;
    }
Copy the code

The problem with hangry is that it doesn’t load on demand.

LanHanShi

Thread insecurity

private static Singleton instance;

    private Singleton(a) {}public Singleton getInstance(a) {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
Copy the code

The problem: With multithreading, threads are not safe.

Thread safety

Methods locking
private static Singleton instance;

    private Singleton(a) {}public synchronized Singleton getInstance(a) {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
Copy the code

With method locking, thread-safety issues are addressed, but each instance is locked, adding overhead.

The code lock
Direct load
private static Singleton instance;

    private Singleton(a) {}public Singleton getInstance(a) {
        if (instance == null) {
            synchronized (Singleton.class) {
                instance = newSingleton(); }}return instance;
    }
Copy the code

Locks are not applied to methods, but to concrete blocks of code. There are situations where you can create two objects.

Double check lock
  • Double-checked locks – no Volatile
private static Singleton instance;

    private Singleton(a) {}public Singleton getInstance(a) {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = newSingleton(); }}}return instance;
    }
Copy the code

There is no case for creating two objects this way. But there is the problem of reordering orders.

  • Double-checked locks – Volatile

private static volatile Singleton instance;

private Singleton() {

}

public Singleton getInstance() {
    if (instance == null) {
        synchronized (Singleton.class) {
            if (instance == null) {
                instance = new Singleton();
            }
        }
    }
    return instance;
}
Copy the code

Static inner class

private Singleton(a) {}public Singleton getInstance(a) {
        return SingletonHolder.INSTANCE;
    }

    static class SingletonHolder {
        private static Singleton INSTANCE = new Singleton();
    }
Copy the code

A static inner class can be loaded on demand.

The enumeration

public enum Singleton {

    INSTANCE;

    public void doSomething(a) {}}Copy the code

Object memory structure

For details, please refer to the previous article.

Object head

Mark Word

Contains HashCode, lock id, object age, and more.

Klass Pointer

The memory address of the Class of the

Length

This exists only in objects of array type and is used to store the length of an array.

The instance data

Holds information about non-static member variables of an object.

Alignment filling

The JVM requires 8-byte alignment

Object allocation

From a GC perspective, the Java heap can be divided into the new generation and the old generation. The size ratio of Cenozoic to old age is: 1:2.

The new generation

Used to store newly generated objects. The Cenozoic era is divided into Eden, SurvivorFrom and SurvivorTo, with a ratio of 8:1:1. The GC algorithm used by the new generation is the replication algorithm.

Eden area

Where new objects are saved after they are created. If it is a large object, go straight to the old age.

SurvivorFrom area

Objects that remain after GC are stored in this section.

SurvivorTo area

SurvivorFrom objects that remain after GC enter this zone.

The old s

The age of an object in the new generation increases by 1 after each GC, and if the object’s age reaches the old age standard (15 by default), it will enter the old age. The GC algorithm used in the old days is the tag clearing algorithm.