preface

  1. What are the JVM memory model, the JAVA Memory Model, and the JAVA Object Model with similar names?
  2. What are the common garbage collection methods? What are the garbage collectors? What are their characteristics?
  3. How does the JVM monitor? Tuning?
  4. What is the internal storage format of class files generated after Java compilation?
  5. What are the processes involved in class loading? What is the parental delegation model?
  6. What’s the difference between volatile and synchronized?
  7. What are optimism locks and pessimism locks? The CAS theory?

All of these questions are well answered in understanding the Java Virtual Machine.

History of Java versions

Features of Java versions

  • Version 1.0 was released in 1996, representing technologies: JVM, Applet, Awt
  • Version 1.1 was released in 1997, representing technologies: JAR file format, JDBC, Javabean, inner class, reflection
  • Version 1.2 was released in 1998, representing technologies: JIT, Collections
  • In 1999, HotSpot virtual machine was released and became the default virtual machine for jdk1.3 and later
  • Version 1.3 was released in 2000, which represents technology: math libraries, JNDI services
  • In 2002, version 1.4 was released. Representative technologies: re, exception chain, NIO, logging classes, XML parsing, etc
  • Version 1.5, released in 2004, represents technology: syntax easier to use, autoboxing, generics, annotations, American drama, foreach, variable length parameters
  • Version 1.6, named java6, was released in 2006. Technology: lock, synchronization, garbage collection, cumulative value algorithm optimization. Announced that the open source
  • Java7 was released in 2009, representing technology: G1 collector, updated class loading architecture
  • Java8 was released in 2014, a long-supported version. Representative techniques: Lambda expressions, STREAM, interface default methods and static methods, Optional, Base64, HashMap improvements (red-black tree)
  • Java9 was released in 2017, a short-term maintenance version. Representative technologies: modular systems, JShell, proprietary methods for interfaces, HTTP2 support, etc. CMS garbage collector deprecated, default garbage collector is G1 (based on single-threaded tag scan compression algorithm)
  • Java10 was released in March 2018, a short-term maintenance version. Representative technologies: VAR, G1 improvement (Multithreaded parallel GC)
  • Java11 was released on 26/9/18, the long-supported version. Representative technologies: new generation garbage collector ZGC (experimental phase), JFR (monitoring, diagnostics), HttpClient, etc

Java memory region division

1. Program counter

  • An indicator of the bytecode line number executed by the current thread
  • Each thread has its own program counter
  • If a Java method is executed, record the bytecode instruction address. Null if Native method is executed
  • No OutOfMemoryError will occur

2. Vm stack

  • Threads are private and have the same life cycle as threads
  • Describes the memory model of Java method execution: each method creates a stack frame to store local variables, method exits, operand stacks, and so on. Each method call corresponds to a stack frame from the virtual machine stack to the process
  • Store basic data types (8 types) and object reference types (Pointers to addresses or handles to objects)
  • StackOverflowError is raised when the request stack depth is greater than the allowed depth of the virtual machine
  • If the dynamic extension still cannot allocate enough memory, an OutOfMemoryError is thrown

3. Local method stack

  • It acts like a virtual machine stack
  • The differences are as follows: Native methods used by the local method stack service VM

4. The heap

  • The memory that a VM manages is the largest
  • An area shared by all threads
  • All object instances are in this shard
  • Can be subdivided into multiple generations

5. Methods area

  • An area shared by all threads
  • Store class information, constants, static variables
  • Also called persistent generation on HotSpot virtual machine
  • Garbage collection behavior rarely occurs in this area because there is little memory to recycle

6. Runtime constant pool

  • Is part of the methods area
  • Used to hold the various literal and symbolic references generated by the compiler

7. Direct memory

  • It is not included in the JVM memory region and is not affected by JVM parameters
  • When the JVM uses a buffer, it allocates memory in this area
  • Be careful to reserve space for this area during configuration, rather than allocating all memory to the JVM
  • -xx :MaxDirectMemorySize specifies, does not specify default as the maximum heap size (-xmx)

HotSpot VIRTUAL machine object

1. Object creation

  • When you receive the new instruction, you first check to see if you can locate the symbolic reference to the class in the constant pool

  • If there is, the class has been loaded, parsed, and initialized. Otherwise load the class.

  • Allocate heap memory according to class university. There are ways to distribute

    • Pointer collision: memory tidy (no compression collation function), only move pointer. Serial, ParNew virtual machine
    • Free list: Memory is not tidy (with compression), to find a free list of enough space. CMS virtual machine

    How to solve the concurrency problem of allocation process

    • Synchronization: CAS+ Retry
    • Memory is pre-allocated by thread, called a local Thread allocation buffer (TLAB). -xx :+/ -Usetlab parameter is determined
  • Object is initialized to zero

  • Set the object header information: which class the object belongs to, the hash code of the object, GC generation age, whether biased locking is enabled, and so on

  • Execute the init method to do the initialization required by the programmer

2. Memory layout of the object

The layout of objects in memory is divided into three areas: object headers, instance data, and alignment padding

2.1 object head

  • The object header contains the runtime data of the object itself, the pointer to its owning class, and the length of the array (if it is an array object).
  • The runtime data area is officially called Mark Word
  • The runtime data area is an unfixed data structure and stores different contents according to different flag bits
  • A type pointer indicates which class instance the object belongs to
  • If it’s an array object it also includes the length of the array

2.2 Instance Data

  • Object actually stores valid information
  • The storage order is influenced by the sharding policy parameters and the source code definition order
  • By default, the allocation policy allocates the length of the field first and allocates the same field together

2.3 Align Padding

  • Not required, placeholder only
  • The size of the object must be an integer multiple of 8 bytes

3. Access and locate objects

  • Use handles: The heap is divided into a separate memory pool for handles, and reference stores handle addresses. Reference does not need to be modified when the object is moved.

  • Direct pointer: reference Indicates the address of the object directly stored. Speed is fast.

Garbage collector and memory allocation strategy

1. Basic concepts

1.1 Collected Objects

The heap, an area of memory in the method area

1.2 Method to determine whether the object is alive

Reference counting method
  • Adds a reference counter to an object
  • Implement a simple
  • Cannot solve the problem of objects referring directly to each other in a loop
  • Representative used: Microsoft COM technology
Accessibility analysis
  • Representatives used: Java, c#
  • The GC roots object is used as the starting point, and when that object is unreachable, the object is proved to be unavailable
  • GC Roots objects include the following types
    • Object referenced in the virtual machine stack
    • The object referenced by the class static property in the method area
    • The object referenced by the constant in the method area
    • Objects referenced by JNI in local methods

1.3 Classification of references

  • Strong references: Assignment after new is ubiquitous and is never reclaimed
  • Soft references: Useful, but not required. Reclaim these objects before an out-of-memory exception
  • Weak references: Weaker than soft references and only survive until the next garbage collection
  • Virtual reference: the weakest reference relationship. Object cannot be obtained by virtual reference. The purpose of existence is to receive a system notification when garbage is collected

1.4 Recovery of method area (permanent generation)

  • The region’s waste collection efficiency is much lower than that of the New Generation (70%-95%)
  • Recycle two types of content: discarded constants and useless classes
  • A condition that determines whether a class is useless
    • All instances of the class are reclaimed
    • The classload that loaded the class is recycled
    • The java.lang.Class object of this Class is not referenced anywhere and cannot be accessed by reflection
  • Useless classes that meet the above criteria can be recycled (not required)

Garbage collection algorithms

2.1 Mark-clear algorithm

  • The basic collection algorithm
  • There are two stages, marking and clearing
  • Disadvantages:
    • The efficiency problem
    • A large number of discrete memory fragments are generated

2.2 Replication Algorithm

  • Divide memory into two equally sized pieces and use one piece at a time
  • When a block is used up, the surviving objects are copied to the other block
  • This algorithm is used by the new generation of modern virtual machines
  • Inadequate:
    • The memory usage is low

The HotSpot VIRTUAL machine divides the new generation memory into a large Eden area and two smaller survivor Spaces. The size ratio is 8 to 1.

2.3 Mark-collation algorithm

  • When the object survival rate is high, a large number of copies will affect the efficiency, so this algorithm is used in the old days
  • The marking process is the same as the mark-clear algorithm
  • The next step is not to clean up the objects, but to move all surviving objects towards a segment, cleaning up memory beyond the boundary

2.4 Generational collection algorithm

  • Different collection algorithms are used according to the object life cycle
  • A large number of Cenozoic objects died and a small number survived
  • Old age objects have a high survival rate, so the algorithm of mark-cleaning or mark-collection is adopted

3. Algorithm implementation of HotSpot

3.1 Enumeration of GC Roots

  • Reachability analysis must stop the world when enumerating GC Roots
  • The JVM currently uses exact GC, where pauses are not checked one by one, but fetched directly from a pre-stored location. (HotSpot is stored in the OopMap data structure)

3.2 security point

  • For efficiency reasons, generating OopMap will only be at specific places, called safe points
  • The selection method of safety point
    • Preemptive interrupts: Not used by modern JVMS
    • Active interrupts: Threads poll for safe-point identifiers and then suspend

3.3 Security Zone

  • For threads with no CPU allocated (sleep), the safe point cannot be handled and is resolved by the safe zone
  • A security zone is a code in which reference relationships do not change
  • When a thread enters a safe zone, the JVM initiates a GC without having to worry about the thread. When it leaves, the GC needs to be checked to see if it is complete, and unfinished achievements need to wait

3.4 Garbage Collector

Serial collector

  • The most basic and developed collector
  • The only option for the new generation collector prior to jdk1.3.1
  • Single-thread collector
  • All other worker threads must be paused during GC
  • Simple and efficient, it is a good choice for single-CPU client mode
ParNew collector

  • Multithreaded version of serial collector
  • The preferred next-generation collector for the SERVER mode JVM
  • In single-CPU mode, performance is no better than serial due to thread switching overhead
Parallel Scavenge
  • The new generation of collectors using replication algorithms, support multithreading
  • Can control throughput rate
    • -xx :MaxGCPauseMillis Maximum garbage collection pause time, which is inversely proportional to throughput
    • -xx :GCTimeRatio Throughput size
  • Provides adaptive adjustment tests
    • -XX:UseAdaptiveSizePolicy
  • Cannot work with the CMS collector
Serial Old

  • An older version of the Serial collector
  • Use a mark-de-clutter algorithm
  • This command is used by VMS in client mode
Parallel Old

  • The Avenge
  • Multithreaded, mark-collation algorithm
  • JDK1.6 is available
Concurrent Marked Sweep (CMS)

  • Old age collector
  • The goal is to minimize GC pauses
  • Does not wait until the old age space is almost full to reclaim (concurrent with the user thread, leaving memory for the user thread). Configuration parameters for – XX: CMSInitiazingOccupanyFraction
  • Use a mark-clear algorithm. The whole process is divided into four steps:
    • Initial tag: STW, which marks objects that GC Roots can associate with, very fast
    • Concurrent markup: GC Roots Tracing process. Time consuming. Execute with the user thread
    • Relabelling: STW, marking an object whose mark changes as a result of the program running during concurrent marking, is longer than the initial mark and much shorter than the concurrent mark
    • Concurrent clearing: Time consuming. Execute with the user thread
  • Advantages:
    • Concurrent collection
    • Low pause
  • Disadvantages:
    • Occupying CPU resources of executing user programs
    • Floating garbage cannot be processed (new garbage generated during concurrent cleanup cannot be processed concurrently)
    • Memory fragmentation problem
Garbage First (G1)

  • Cutting edge garbage collector
  • Jdk1.7 is released, replacing the CMS of JDK1.5
  • The heap memory layout is different from that of other collectors in that the new generation and old generations are no longer physically isolated, but Region collections
  • According to the garbage collection value of each region, the region is added to the priority queue. Ensure that each GC can achieve the highest collection rate in a limited time
  • Remember Set ensures that cross-region regions do not require full heap scans
  • Running steps
    • Initial tag: STW, very short. Marks the object associated with GC Roots
    • Concurrent marking: Reachability analysis, time-consuming. Can be executed concurrently with user threads
    • Final tag: STW, which corrects the part of tag change caused by user thread running in concurrent tag phase
    • Screening recovery: Sort the recovery value of each region and make a recovery plan
  • advantages
    • Parallelism and concurrency
    • Generational collection
    • Space defragmentation: no memory fragmentation
    • Predictable pauses: Almost real-time garbage collection

4. Memory allocation and reclaiming policies

4.1 Objects are allocated in Eden area first

  • When the Eden area is out of space, the JVM issues a Minor GC

    Minor GC vs Full GC

    • Minor GC: New generation GC occurs frequently and quickly
    • Major/Full GC: Old gc, slow

4.2 Large objects directly into the old age

  • Typical examples: long strings or arrays
  • Large objects are unfriendly to JVMS, leading to frequent GCS

4.3 Objects of long-term survival will enter the old age

  • The first minor GC that passes through Eden survives and is moved to survivor with age +1
  • The age of an object is +1 for each minor GC that survivor passes through
  • If you reach a certain age (15 by default), you will enter the old age. Parameter: -xx: MaxTenuringThreshold

4.4 Dynamic age judgment

  • It is not always necessary to reach a set age to enter the old age
  • When the size of all objects of the same age in a survivor space is greater than half of the space, the objects greater than or equal to this age directly enter the old age

4.5 Guarantee of space allocation

  • Before the Minor GC executes, it checks to see if the maximum available contiguous space of the old generation is greater than the total space of all objects of the new generation
  • If not, judge whether it is larger than the average size of objects promoted to the old age
  • If the conditions are not met, full GC is performed

5. JVM performance monitoring

5.1 JDK command line tools

  • JPS: View running VM processes
  • Jstat: statistics monitoring tool. Parameters are:
    • -class: indicates the class loading information
    • – GC: monitors the heap, including Eden, survivor, old age, persistent generation space, and GC time
    • -gccapacity: the same as -gc, but focuses on the maximum and minimum space of each region
    • -gcutil: same as -GC, but focuses on the percentage of occupancy
    • -gCCause: same as -gcutil, but outputs the cause of the last GC
    • -gcNew: Monitor the new generation
    • -gcnewCapacity: the same as -gcnew, which focuses on the maximum and minimum space
    • -gcold: Watch the old days
    • -gcoldcapacity: the same as -gcold, which indicates the maximum and minimum space
    • – gcpermCapacity: indicates the maximum and minimum capacity of the permanent generation
    • – Compiler: Indicates JIT compilation information
    • Printcompilation: JIT compilation method
  • Jinfo: Java configuration information tool. View and adjust VM parameters in real time
  • Jmap: Memory mapping tool. Parameters are:
    • -dump: generates a Java heap storage snapshot
    • – finalizerInfo: objects to be executed with finalize method
    • -heap: Displays detailed Information about the Java heap, including the payback period, parameter configuration, and generation status
    • -histo: indicates heap object statistics, including classes, instances, and total capacity
    • -permstat: indicates the permanent generation memory status
    • -f: forcibly generates a snapshot
  • Jhat: Analyzes the dump file. Not usually. Use third party VisualVM, Eclipse, Memory Analyzer, Heap Analyzer, etc
  • Jstack: A Java stack tracker used to locate the current stack status of a thread that has been paused for a long time

5.2 JDK visualization tools

  • jconsole
  • VisualVM

5. Class file structure

1. Class file structure overview

  • A class file is a set of binary streams in 8-bit byte base units
  • Each data item is strictly and compactly arranged
  • Data larger than 8-bit bytes is divided into 8-bit bytes in ascending order
  • Pseudo-structure similar to c language structure is used for storage
  • Pseudo-structures have two types of data:
    • Unsigned: Basic data types, including U1, U2, U4, u8, where numbers represent the number of bytes
    • Table (compound structure) : ends with _info
  • The following table is strictly limited in order, number, and number of bytes stored

2. magic

  • First four bytes
  • Determines whether the class file can be accepted by the JVM for identification
  • Value is: 0 xcaffebabe

3. The version number

  • Minor-version: 5-6 bytes
  • Major-version: 7-8 bytes

4. The constant pool

  • Class file in the resource repository, the number of fixed, in the entry by a U2 type of data to specify the capacity of the constant pool
  • The 0th entry in the constant pool is left empty so that some subsequent constant pool index values are set to 0 if they do not reference any of the constant pools
  • There are two main types of storage
    • Literals: text strings, final constants, etc
    • Symbolic references: Full names of classes and interfaces, field names and descriptors, method names and descriptors
  • Each constant entry in the constant pool is a table, and each table starts with an identifier bit of type U1 that represents the type of the constant
  • The item types of the constant pool are as follows:

5. Access identification

  • Two bytes after the constant pool
  • Identifies whether the class is a normal class, interface, enumeration, or annotation. Public or private etc

6. Class index, parent index, and interface index collection

  • The class index, parent index is u2 type data, and the interface index is -group U2 type data collection
  • Used to determine the inheritance of this class

7. Set of field tables

  • Describes variables declared in an interface or class, excluding local variables
  • This includes: scope, static modifier, final modifier, data type, volatile, TRANSIENT, and name

8. Method table collection

  • Similar to a collection of field tables
  • Includes access identifiers, name indexes, descriptor indexes, and property list collections

9. Property sheet collection

  • Proprietary information used to describe certain scenarios
  • There are no order, length, or content restrictions, as long as they do not duplicate existing attribute names

Bytecode instructions

1. An overview of the

  • JVM instructions = opcode (1 byte) + operand
  • Most instructions have only opcodes and no operands
  • The number of opcodes does not exceed 256 (2^8)
  • Because the operands are not aligned, more than one byte of data needs to be reconstructed by the runtime. The advantage is that you omit a lot of padding and spacing, and the disadvantage is that you lose performance

2. Load and store instructions

  • Used to transfer data back and forth between the local variable table and operand stacks in a stack frame
  • Load local variables into operation stack: ILoad, ILoAD_,lload,fload,dload, ALOad (Reference Load)
  • From the operand stack storage to local variables: istore, istore_, lstore, fstore, dstore, astore
  • Constants are loaded onto the operand stack: bipush,sipush

3. Operation instruction

  • Perform an operation on two values on the operand stack and store them back
  • Byte, short, char, and Boolean all use int directives instead
  • Add instructions: iadd, ladd, fadd, dadd
  • Subtraction instruction: isub, Lsub…
  • Multiplication instruction: IMul,…
  • Division instruction: IDEV,…
  • .

4. Type conversion instruction

  • Wide type conversion: no need to display all conversion instructions
    • Int to long, float, double
    • Long goes to float, double
    • Float switch double
  • Narrow type conversion: use conversion instructions must be displayed
    • Including: i2b, i2c, i2s l2i…

5. Object creation and transformation instructions

  • Directive to create class instances: new
  • Instructions for creating arrays: newarray, anewarray, multianewarray

6. Operand stack management instructions

  • One or two operands at the top of the stack: pop, POP2
  • Duplicate top data and push it again: DUP, duP2
  • Swap the top two elements of the stack: swap

7. Control transfer instruction

  • Conditional branches: IFEQ, IFLT…
  • Compound condition branches: Tableswitch, LookupSwitch
  • Unconditional branches: Goto, RET

8. Method calls and return instructions

  • Invoke the instance method of the object: invokevirtual
  • Invoke the interface method: InvokeInterface
  • Call special methods: initialization, parent methods, etc. : Invokespecial
  • Invoke the static method: Invokestatic

9. Exception handling instructions

  • athrow

10. Sync command

  • Synchronized corresponds to monitorenter, monitorexit

Class loading mechanism and class loader

1. Class loading mechanism

1.1 an overview of the

The entire life cycle of a class begins when it is loaded into memory and ends when it is unloaded from memory

  • loading
  • validation
  • To prepare
  • parsing
  • Initialize the
  • use
  • uninstall

Class loading time is not mandatory, but during initialization, classes must be initialized if and only if:

  • New, getstatic, putstatic, invokestatic. The corresponding Java code is: new, set the static field, call the static method
  • When the java.lang.reflect package reflects a class
  • Initialize a class if the parent class has not already been initialized (interfaces do not require this)
  • Initialization of the main class when the virtual machine starts
  • Java. Lang. Invoke. MethodHandle specific analytical results

1.2 loading

  • Get binary byte streams by class name: source can be JAR, WAR, etc. It can also be a network, a proxy, etc.
  • Transform the static storage structure represented by this byte stream into the runtime data structure of the method area
  • Generate a java.lang.Class object in memory as an access point to the method area Class

1.3 validation

  • To ensure that the byte stream in the class file contains the information required by the virtual machine
  • Protecting the VIRTUAL machine itself is an important task to prevent malicious attacks
  • The verification includes:
    • File format verification: magic number is 0xCAFEBABE, primary and secondary version numbers are allowed by the current JVM, constant pool type is correct, etc
    • Metadata validation: whether a parent class exists, whether a final class inherits, whether a non-abstract class implements all methods, and so on
    • Bytecode validation: most complex. Verify that data in and out of the stack are of the same type, that instructions do not jump outside the method body, and so on
    • Symbol reference verification: whether the corresponding class can be found by name in symbol reference

1.4 to prepare

  • The phase that allocates memory and sets initial values for class variables (static types)
  • The initial value generally refers to 0, not the value initialized by the code. Unless a static variable is specified as final
  • The following are the default initial values

1.5 analytical

  • Replaces symbolic references in the constant pool with direct references
    • Symbolic references: A set of symbols describing the target of a reference, independent of the JVM memory layout
    • Direct reference: A pointer or offset address that points directly to a target, depending on the memory layout of the JVM
  • Analysis includes:
    • Class or interface resolution
    • Field analytical
    • Class method resolution
    • Interface method parsing

1.6 the initialization

  • Actually executes the Java code defined in the class
  • The process of executing a class constructor method
  • The client method is a combination of all static variables and static code
  • This method is multithreaded safe to execute

2. Class loader

2.1 Class loaders

  • Exists outside the JVM to implement class loading operations
  • The uniqueness of any class is determined by both the class loader and the class itself
  • Comparing classes for equality only makes sense if the same classloader is being loaded

2.2 Classification of class loaders

  • Start the class loader: The JVM recognizes and loads the specific JAR in the lib directory
  • Extension class loader: Loads jars for the lib/ext directory
  • Application loader: load user class, ClassLoader implementation, users can use directly
  • Custom loader: The custom loader relationship is as follows:

2.2 Parental delegation model

  • The hierarchical relationship between class loaders is called the parent delegate model
  • Requires that all loaders except the top-level start class loader must have a parent loader (through composition rather than inheritance)
  • How it works: When a class loader receives a load request, it first does not attempt to load the class itself. Instead, it delegates the request to the parent class. So all requests are loaded by the startup class loader first. Subclasses are loaded when the parent class cannot be loaded
  • What it does: Ensures that the base class is the same class in all class loaders, otherwise the Java type system would be a mess
  • Application: Different Tomcat services should be isolated, and common parts should be reused. A variety of classes need to be loaded, all through the parent delegate model

JVM bytecode execution mechanism

1. Runtime stack structure

1.1 an overview of the

  • Data structures that support method invocation and execution
  • The area of the Java virtual machine stack in the JVM memory model
  • Store local variable table, operand stack, dynamic link, method return address and other information
  • Each method call corresponds to the virtual machine stack on to off process

1.2 Local variation scale

  • Store method parameters and local variables
  • Unlike class member variables, local variables are initialized by default
  • Local variable table index 0 stores this by default

1.3 Operand stack

  • Method, various bytecode instructions are pushed onto and off the operands during execution

1.4 Dynamic Connection

  • Each stack frame has a reference to the method that the stack belongs to for dynamic concatenation

1.5 Method returns the address

2. Method calls

2.1 analytical

2.2 the dispatch

  • Static dispatching
  • Dynamic dispatch
  • Single dispatch and multiple dispatch
  • Virtual machine dynamic assignment

3. Method execution

  • Explain to perform
  • Compile implementation

Java memory model

1. Efficiency and consistency

  • The cache resolves the speed contradiction between processor and memory
  • But it introduces the problem of cache consistency
  • Processor optimizations and compiler instruction rebeats can also cause cache inconsistencies

2. Java memory model

2.1 an overview of the

  • Properties: Built around how atomicity, visibility, and orderliness are handled in concurrency
  • What it does: The JVM defines the JMM to mask differences in memory access across hardware and operating systems to achieve consistent memory access across platforms
  • Target: Defines access rules for variables, including storing variables into memory and fetching variable values from memory. Variables here refer to instance fields that will be shared, class fields. Local variables that are not shared are not included
  • Rule: All variables are stored in main memory, and each thread has its own working memory, which holds a copy of the main memory variables. Thread operations on variables must be in working memory, not main memory. Threads cannot access each other, and variable passing between threads needs to pass through main memory.

2.2 Main memory and working memory interaction protocol

Atomic operations included in the protocol:

How a variable is copied from main memory to working memory, and synchronized from working memory back to main memory, the Java memory model defines eight operations to accomplish this, each of which is atomic:

  • Lock: Works with main memory variables, which are exclusive to a thread
  • Unlock: Works with the main memory variable. It can be unlocked by other threads
  • Read: Acts on main memory variables, transferring a variable value from main memory to working memory for load
  • Load: Acts on a working memory variable, putting the value of the read operation from main memory into a copy of the working memory variable
  • Use: functions with working memory variables that are passed to the execution engine
  • Assign: Assigns the value of the execution engine to the working memory variable
  • Store: Acts on working memory variables that are passed to main memory for write operations
  • Write: works with the main memory variable. The value obtained by store is put into the main memory variable
Agreement rules
  • Primary memory is copied to working memory: read and load must be executed sequentially
  • Working memory synchronization back to main memory: Store and write must be executed sequentially
  • There is no requirement for continuous execution, that is, other operations can be inserted in between
  • One of the read and load, store and write operations is not allowed to occur separately
  • Before using use and store, you must perform assign and load operations. That is, variables can only be born in main memory
  • Only one thread can lock a variable at a time, but the same thread can lock it several times before it can be unlocked
  • When the lock is executed, the values of variables in the working memory will be cleared, and the load and assign values need to be re-loaded
  • Unlock cannot be performed without being locked
  • To execute unlock, you must first synchronize the variable values back to main memory

2.3 The Java memory model defines special rules for Volatile

Once a variable is defined as volatile, it has two properties:

  • Visibility: Ensure that this variable is visible to all threads. That is, when one thread changes a variable, another thread immediately learns about it. Ordinary variables need to pass through main memory to complete.

    Visibility does not guarantee concurrency safety because operations may not be atomic.

  • Disallow instruction reordering optimization. Ensure that the order in which variables are assigned is consistent with the order in which code is executed.

2.4 Java Memory model special rules for long, double types

  • For 64-bit data types, JVM runs divide variable reads and writes that are not volatile into two 32-bit operations. That’s the nonatomic agreement for long and double
  • However, the JVM implements atomic manipulation of 64-bit data. So you don’t need to declare it volatile specifically

2.5 Atomicity, visibility and order

  • Atomicity: The rules of the Java memory model guarantee that access to basic data types is atomic. A wider range of atomicity is guaranteed by synchronized and lock
  • Visibility: The Java memory model implements visibility through main memory by synchronizing new values back to main memory after a variable has been modified and flushing new values from main memory before reading the variable. Volatile guarantees visibility of variables in multithreaded operations, whereas normal variables do not. Synchronized and final can also achieve visibility
  • Orderliness: This thread observes that all operations are in order. When you observe another thread in one thread, all operations are out of order. Volatile and synchronized ensure that thread operations are ordered.

Thread safety and locking

1. Thread status

At any point in time, a thread can have only one state

  • New: not started after being created
  • Runable: Running or waiting for the CPU to fragment execution time for it
  • Waiting: no CPU time allocated, Waiting to be awakened by another thread. This state occurs in the following methods
    • Ojbect.wait method without timeout
    • Thread.join method without timeout
    • LockSupport. Park method
  • Timed Waiting: CPU time is not allocated but does not need to be woken up after a certain time.
    • Thread.sleep()
    • Ojbect.wait method with timeout
    • Thread.join method with timeout
    • LockSupport parkNanos method
    • LockSupport parkUntil method
  • Blocked: A thread enters a synchronization area and waits to obtain the status of an exclusive lock
  • Treminated: The execution ends

2. Thread-safe implementation method

2.1 Mutex Synchronization (blocking synchronization, pessimistic locking)

  • Synchronization: When multiple threads concurrently access data, only one thread can be used at a time
  • Mutex: Means of achieving synchronization, including: Critical sections, Mutex, Semaphore
  • Synchronized: indicates the basic mutually exclusive synchronization method. After compilation, monitorenter and Monitorexit directives are added before and after the code is synchronized. When monitorenter is executed, it attempts to acquire the lock on an object, incrementing the lock count (reentrant) if it already has it, otherwise the block knows the lock is released. Blocking calls the kernel and consumes a lot of switching time. JVM optimizations are preceded by a spin wait.
  • ReentrantLock: API level mutex, with some advanced features. Such as waiting can be interrupted, can achieve fair lock and so on. Default is unfair.
  • Disadvantages of mutex synchronization: performance issues with thread blocking and wake up

2.2 Non-blocking Synchronization (Optimistic Locking)

  • Hardware is required to ensure atomicity of operations and collision detection
  • CAS: compare-and-swap, typically non-blocking synchronization. Contains three operands
    • Memory location: V
    • Old expected value: A
    • New value: B
  • CAS updates V only when V meets A. Otherwise, CAS does not update V. Returns the old value of V, whether updated or not. This procedure is an atomic operation
  • Disadvantages of CAS: ABA problem: Old values changed and then changed back cannot be sensed

ThreadLocal

  • Make variables that do not need to be accessed by multiple threads exclusive to a single thread

3. Lock optimizations

JDK1.6 implements various lock optimization techniques for high concurrency

3.1 Spin locking and adaptive spin

  • Spin lock: While a thread is waiting, instead of hanging, it executes a busy loop.
  • Adaptive spin lock: Automatically adjusts the spin time based on the last spin time and owner status

3.2 lock elimination

  • When the compiler runs, it automatically detects locks that can’t possibly have shared data contention and then removes them

3.3 lock coarsening

  • To extend the scope of a piecemeal lock synchronization operation out of the entire sequence

3.4 Lightweight Lock

  • As opposed to traditional locks implemented using operating system mutex.
  • The CAS operation avoids the overhead of using mutex

3.5 biased locking

  • Further improve performance by eliminating data synchronization without contention
  • In the case of no contention, the entire synchronization is eliminated, and no CAS is done