Chapter 1 abbreviated
Chapter 2 Java Memory Regions and Out-of-Memory Exceptions
runtime data area
- program counter
- Java virtual machine stack
- native method stack
- Java heap
- method area
- Runtime constant pool (part of the method area)
- Direct memory (not part of the data area, just for easy explanation)
Program counter:
The line number indicator of the bytecode executed by the current thread
For multithreading, in order to restore the correct execution position after thread switching, each thread needs to have an independent program counter, and the counters between each thread are mutually Does not affect, independent storage.
Java virtual machine stack:
The memory model of Java method execution stores information such as local variable tables, operand stacks, dynamic links, method exits, etc. The process of each method from invocation to completion of execution corresponds to a stack frame in the virtual machine stack. stack process.
native method stack
Serves the methods used by the Native
virtual machine, and the virtual machine stack serves the virtual machine execution Java
methods (that is, bytecode)
Java heap
The largest block in memory. Holds object instances and is the main area managed by the garbage collector.
method area
Store data such as class information, constants, static variables, and code compiled by the just-in-time compiler that have been loaded by the virtual machine
runtime constant pool
A part of the method area, used to store various literals and symbolic references generated at compile time.
object creation process
- class loading check
- Allocate memory and initialize memory space to zero value
- Object settings, such as which instance of the class the object is, how to find the metadata information of the class, the hash code of the object, the GC generation age of the object, etc.
- execution
init
method
OutOfMemoryError exception
- Java heap overflow: The Java heap is used to store object instances. As long as objects are continuously created and
GC Roots
there is a reachable path between the objects to avoid the garbage collection mechanism from clearing these objects, then the number of objects will reach the maximum heap capacity limit. A memory overflow exception is generated - Virtual machine stack and native method stack overflow
- Method area and runtime constant pool overflow: A large number of Classes are often dynamically generated, for example
cglib
, a large number ofjsp
or dynamically generatedjsp
files, etc. - Native direct memory overflow
Chapter 3 Garbage Collector and Memory Allocation Strategy
Overview: GC is mainly concerned with the memory of the Java heap and method area
reference counting algorithm
Mainstream virtual machines do not choose this method to manage memory.
Add a reference counter to the object. Whenever there is a reference to it, the counter value is incremented by 1; when the reference is invalid, the counter value is decremented by 1; the object whose counter is 0 at any time is impossible to be used again.
Disadvantage: It is difficult to solve the problem of circular references between objects.
Reachability Analysis Algorithms
Definition: Through a series of GC Roots
objects called " " as the starting point, the search starts from these nodes, and the search path is called the reference chain. When an object GC Roots
does not have any reference chain, it is proved that the object is not available. use.
GC Roots
The objects include the following:
1. Objects referenced in the virtual machine stack (local variable table in the stack frame).
2. Objects referenced by class static properties in the
method area 3. Objects referenced by constants in the method area
4. Objects referenced in the local method stack JNI
(that is, Native
methods in general)
The main recycling of the method area consists of two parts: abandoned constants and useless classes
Garbage Collection Methods
- mark-sweep algorithm
- Replication algorithm:
Eden
sumSurvivor
ratio is 8:1 - mark-collate algorithm
- Generational collection algorithm: the new generation uses the copy algorithm, and the old generation uses the mark-clean or mark-sort algorithm
Garbage collectors: CMS and G1
recycling strategy
Minor GC
The difference between andMajor GC
: the former occurs in the new generation, the latter occurs in the old generation- Large objects (very long strings and arrays) go directly to the old generation
- Long-lived objects will enter the old generation
- Dynamic object age determination
- space allocation guarantee
Chapter 4 Virtual Machine Performance Monitoring and Troubleshooting Tools
JDK main command line monitoring tools:
- jps: Displays all HotSpot virtual machine processes in the specified system
- jstat: used to collect running data of all aspects of the HotSpot virtual machine
- jinfo: display virtual machine configuration information
- jmap: Generate virtual machine memory dump snapshot (headdump file)
- jhat: used to analyze the headdump file, it will build an HTTP/HTML server, allowing users to view the analysis results on the browser
- jstack: show thread snapshots of virtual machines
JDK Visualizer
- JConsole: Visual monitoring and management tool based on JMX
- VisualVM: All-In-One Troubleshooting Tool
Chapter 5 Tuning Case Analysis and Practice
slightly
Chapter 6 Class File Structure
The structure of the class file
Two data types :
- Unsigned numbers: used to describe numbers, index references, quantitative values, or to form string values according to UTF-8 encoding
- Table: a composite data type composed of multiple unsigned numbers or other tables as data items , ending with "_info"
Class file
- first 4 bytes: 0xCAFEBABE
- 5th and 6th bytes: minor version number
- 7th and 8th bytes are major version number
- constant pool
- access flag: used to identify some classes or interfaces Hierarchical access information
- class index, parent class index and interface index collection
- field table collection: used to describe the variables declared in the interface or class
- method table collection
- property table collection (Class file, field table, method table can all be carry)
The constant pool mainly stores two types of constants :
1. Literals
- text strings - constant values
declared as 2. Symbolic references - fully qualified names of classes and interfaces - field names and descriptors - method names and descriptorsfinal
bytecode instructions
The instruction of the Java virtual machine consists of a byte- length number representing the meaning of a particular operation (called an opcode, Opcode) followed by zero or more parameters (called an operand, Oprands) that represent the required parameters of the operation ) constitutes.
Note : Most of the instructions do not support integer types byte
, char
and short
, and boolean
, at compile time or runtime, the data of the byte
sum short
type is sign-extended to the corresponding int
type data, and the boolean
sum char
type data is zero-extended to the corresponding int
type data . .
Chapter 7 Virtual Machine Class Loading Mechanism
concept:
Class loading mechanism: The virtual machine loads the data describing the class from the Class file to the memory, and verifies, converts, parses and initializes the data, and finally forms a Java type that can be directly used by the virtual machine.
Note: Types are loaded, linked, and initialized while the program is running.
Class life cycle: a total of 7 stages, as shown in the figure
There are only 5 situations in which a class must be initialized immediately:
1. Using an new
instantiated object, reading or setting a static field of a class, calling a static method
of a class 2. Making a reflective call to a class
3. When initializing When a class, its parent class has not been initialized
4. When the virtual machine starts, the user needs to specify a main class to be executed (the class containing main()
the method)
5. When using the dynamic language support of JDK 1.7, If the last parsing result of an java.lang.invoke.MethodHandle
instance is the method handle of , , and the class corresponding to this method handle has not been initializedREF_getStatic
REF_putStatic
REF_invokeStatic
The process of class loading:
- load
- Get the binary byte stream defining a class by its fully qualified name
- Convert the static storage structure represented by this byte stream into the runtime data structure of the method area
- Generate an
java.lang.Class
object representing this class in memory as an access entry for various data of this class in the method area
- verify
- file format validation
- metadata validation
- Bytecode Verification
- Symbolic reference verification
- Preparation : In the stage of formally allocating memory for class variables and setting the initial value of class variables, the memory will be allocated in the method area
- Resolution : The process by which the virtual machine replaces the symbolic references in the constant pool with direct references
- Initialization: The process of executing a class constructor
<clinit>()
method (including assignment of class variables and static statement blocks)
class loader
Note: Comparing two classes for "equal", as long as the class loader that loads them is different, the two classes must not be equal.
Parent delegation model
Working process: If a class loader receives a class loading request, it will not try to load the class by itself first, but delegate the request to the parent class loader to complete, which is the case for each level of class loader , so all load requests should eventually be sent to the top-level startup class loader, and only when the parent loader reports that it cannot complete the load request (the required class is not found in its search scope), the child loader will Will try to load it myself.
Chapter 8 Virtual Machine Bytecode Execution Engine
Stack frame: is a data structure used to support the virtual machine for method invocation and method execution. As shown below
- Local variable table: a set of variable value storage spaces used to store method parameters and local variables defined inside the method
- Operand stack: last in first out (LIFO)
- Dynamic connection: Each stack frame contains a reference to the method to which the stack frame belongs in the runtime constant pool. This reference is held to support dynamic connection during method invocation.
- method return address
method call
- Resolution: Determined during compilation, during the resolution phase of class loading, all involved symbolic references will be converted into determinable direct references.
- assign
- Dynamically typed language support: JDK 7 adds
invokedynamic
bytecode instructions
Chapter 9 Cases and Practices of Class Loading and Execution Subsystems
slightly
Chapter 10 Early (compile-time) optimizations
Three types of compilers
- Front-end compilers: Sun's Javac, Incremental Compiler (ECJ) in Eclipse JDT
- JIT compiler (backend compiler): C1, C2 compiler of HotSpot VM
- AOT Compiler: GNU Compiler for the Java (GCJ), Excelsior JET
Javac compilation process
- Compilation and Fill Symbol Process
- Annotation processing for plug-in annotation processors
- Analysis and bytecode generation process
A taste of Java syntactic sugar
- Generics and Type Erasure: The implementation of generics in Java is called type erasure, also known as pseudo-generics
- Autoboxing, unboxing, and traversal loops
- Conditional compilation: using an if statement with a constant condition
Chapter 11 Late (Runtime) Optimization
Overview:
Just-in-time compiler :
When the virtual machine finds that a method or code block runs very frequently, it will identify these codes as "Hot Spot Code". In order to improve the execution efficiency of hot code, at runtime, virtual The machine will compile this code into native platform-specific machine code and perform various levels of optimization.
Chapter 12 The Java Memory Model and Threads
Java memory model
The interaction between threads, main memory, and working memory:
Interaction between memory
- lock
- unlock
- read
- load
- use
- assign (assignment)
- store
- write
volatile keyword
Two features :
1. Guarantee this variable is visible to all threads
2. Disable instruction reordering optimization
Note : volatile
This variable is guaranteed to be visible to all threads, but the operation of the variable is also unsafe under concurrency
Usage scenarios :
- The result of the operation does not depend on the current value of the variable, or it can ensure that only a single thread modifies the value of the
variable - The variable does not need to participate in the invariant constraint with other state variables
three characteristics
atomicity
- Access to basic data types is atomic (
long
anddouble
excepted) - To use
lock
andunlock
satisfy a wider range of atomicity, the virtual machine providesmonitorenter
andmoniterexit
bytecode instructions, which are reflected in Java code as synchronized blocks—synchronized
keywords
- Access to basic data types is atomic (
visibility
- Visibility is achieved by synchronizing the new value back to main memory after the variable is modified, and flushing the variable value from main memory before the variable is read, relying on main memory as the delivery medium
volatile
,synchronized
andfinal
both enable visibility
orderliness
- If observed in this thread, all operations are in order; if one thread is observed in another thread, all operations are out of order.
- The first half of the sentence refers to the "semantics of serial performance within the thread", and the second half of the sentence refers to the phenomenon of "instruction reordering" and "synchronization delay between working memory and main memory".
happens-before principle
Refers to the partial order relationship between the two operations defined in the Java memory model. If operation A occurs first before operation B, it actually means that before operation B occurs, the effect of operation A can be observed by operation B. "Affects" include changing the value of a shared variable in memory, sending a message, calling a method, etc.
thread
implementation of the thread
- Implemented using kernel threads
- Implemented using user threads
- Mixed implementation using user threads and lightweight threads
- Implementation of Java Threads
Java thread scheduling
- Cooperative thread scheduling: the execution time of a thread is controlled by the thread itself
- Preemptive thread scheduling: the execution time is allocated by the system (the way Java uses)
state transition
- New (New)
- Runnable
- Waiting indefinitely (Waiting): need to wait to be explicitly woken up by other threads
- Timed Waiting: The system will automatically wake up after a certain period of time
- Blocked
- Terminated
Chapter 13 Thread Safety and Lock Optimization
Five types of data shared by various operations
- Immutable : The basic data type
final
can be declared as; all variables with state in the object are declared asfinal
- Absolutely thread-safe : the caller does not need any additional synchronization measures regardless of the runtime environment
- Relative thread safety : For some sequential calls in a specific order, additional synchronization methods may be required on the calling side to ensure the correctness of the calls. For example
Vector
, a collection of method wrappers for ,HashTable
, .Collections
synchronizedCollection()
- Thread compatibility : The object itself is not thread-safe, but it can be guaranteed that the object can be used safely in a concurrent environment by using synchronization methods correctly on the calling side. For example
ArrayList
andHashMap
. - Thread opposition : Code that cannot be used concurrently in a multithreaded environment, regardless of whether the caller has taken synchronization measures. For example
Thread
classsuspend()
andresume()
methods.
How to implement thread safety
- Mutual exclusion synchronization :
synchronized
keyword andReentrantLock
ReentrantLock
three functions added:
- wait for interruptible
- Fair lock available
- Locks bind multiple conditions
- Non-blocking synchronization : CAS operations, such as the integer atomic class in the JUC package, in which the
compareAndSet()
andgetAndIncrement()
other methods use theUnsafe
CAS operations of the class - No synchronization scheme : If a method does not involve shared data at all, no synchronization is required
- reentrant code
- Thread-local storage: If the code that shares the data can be guaranteed to execute in the same thread, it is possible to limit the visibility of the shared data to the same thread.
java.lang.ThreadLocal
The function of thread local storage is implemented through classes.
lock optimization
- Spin locks and adaptive locks : Let the thread that requests the lock later wait and perform a busy loop (spin). Avoids the overhead of thread switching, but only applies when the lock is held for a short time.
- Lock elimination : Refers to the virtual machine just-in-time compiler that requires synchronization on some codes during runtime, but it is detected that there is no possibility of shared data contention. For example , the
String
concatenation of strings. - Lock coarsening : If a series of consecutive operations lock and unlock the same object, the scope of lock synchronization will be extended to the outside of the entire sequence of operations.
- Lightweight Locks : Use CAS operations to eliminate mutexes used for synchronization without contention.
- Biased lock : The entire synchronization is eliminated in the absence of competition, and even the CAS operation is not performed.