This is the 21st day of my participation in the August More Text Challenge

JVM

Runtime data area

According to the Java Virtual Machine Specification (Java SE 7 Edition), the following figure shows the memory managed by the Java VIRTUAL Machine.

Program counter

Small memory space, thread private.

The bytecode interpreter works by changing the value of the program counter to select the next bytecode instruction that needs to be executed (mainly the bytecode file of the next instruction).

Basic functions such as branching, looping, jumping, exception handling, and thread recovery rely on program counters.

If a thread is executing a Java method, this counter records the address of the virtual machine bytecode instruction being executed.

If the Native method is being executed, this counter records the value (Undefined).

This memory region is the only one in the Java Virtual machine that does not specify any OutOfMemoryError cases.

Java virtual machine stack

The thread is private and has the same life cycle as the thread.

It describes the memory model of Java method execution: each method execution creates a Stack Frame to store information such as local variable table, operand Stack, dynamic link, method exit, etc.

Each method from the call to the end of execution, corresponds to a stack frame from the virtual machine stack to the stack process.

Local variation scale: Store basic types known at compile time (Boolean, byte, char, short, int, float, long, double), The object reference type and the returnAddress type refer to the address of a bytecode instruction.

StackOverflowError: Stack depth of thread request is greater than the depth allowed by the virtual machine. OutOfMemoryError: If the vm stack can be dynamically expanded and sufficient memory cannot be allocated during the expansion.

Local method stack

It differs from the Java virtual machine stack in that the Java virtual machine stack performs Java methods (that is, bytecode) services for the virtual machine, whereas the Native method stack serves Native methods used by the virtual machine.

StackOverflowError and OutOfMemoryError exceptions also occur.

The Java heap

Threads share

For most applications, the Java heap is the largest chunk of memory managed by the JVM.

The main store is object instances and arrays.

Multiple Thread Local Allocation buffers (TLabs) are allocated internally.

It can be physically discontinuous, but logically continuous.

The heap is created when the virtual machine is started.

OutOfMemoryError: Thrown if there is no memory in the heap to complete instance allocation and the heap can no longer be extended (the number of heaps needed to calculate exceeds the number of heaps available to the automatic storage management system).

Methods area

A shared memory area that stores loaded class information, constants, static variables, code compiled by the just-in-time compiler, and so on.

The method area is created when the virtual machine starts.

If the memory in the method area cannot satisfy the allocation request, the Java Virtual machine raises an OutOfMemoryError.

Run-time constant pool

A part of the method area that holds the various literal and symbolic references generated at compile time.

Both compile time and run time (intern() of String) can pool constants.

OutOfMemoryError is excluded if memory is limited and cannot be applied

When creating a class or interface, the Java Virtual machine raises an OutOfMemoryError if the construction of the runtime constant pool requires more memory than is available in the Java Virtual machine’s method area.

Direct memory

Part of the non-running data area of the virtual machine

In JDK 1.4, the NIO (New Input/Output) class introduced a Channel – and buffer-based I/O method, which can use Native libraries to allocate out-of-heap memory directly. It then operates through a DirectByteBuffer object stored in the Java heap as a reference to this memory. Can avoid time-consuming data operations back and forth between the Java heap and Native heap. OutOfMemoryError: Is limited by native memory and occurs when the sum of memory regions is greater than the physical memory limit, resulting in dynamic expansion.

Garbage collector and memory allocation strategy

The three areas of the program counter, virtual machine stack and local method stack are born and die with the thread, and the pins in the stack perform the operation of loading and unloading as the method enters and exits.

Java heap area and method, an interface of multiple implementation classes need memory may not be the same, a method of multiple branch need memory may not be the same, we only in a program at run-time know which object is created, this part of the memory allocation and recovery are dynamic, recycling concern is this part of the memory.

Determines whether an object needs to be reclaimed

Reference counting method

Each object has a reference counter, which is incremented by one when the object is referenced once, and decayed by one when the reference is invalid once. Objects with a counter of 0 are garbage objects that can be collected by GC.

Disadvantages: Objects in the Java heap that keep referring to each other cannot be recycled, making circular references difficult to solve

Reachable algorithm

The search starts with GC Roots as the starting point, and the path taken from these nodes is called the reference chain. Then the objects in the chain are live objects.

Objects that cannot be reached by GC Roots can be collected by GC at any time.

Available as objects for GC Roots:

  • The object referenced in the virtual machine stack (the local variable table in the stack frame)
  • Objects referenced by static variables and constants in the method area
  • Objects referenced by JNI(commonly referred to as Native methods) in the Native method stack

reference

The previous algorithm determines survival by reference.

The following four references are in decreasing intensity.

Strong reference

Object obj = new Object(); The created obj points to the heap space where the Object instance resides.

Strong references are the most commonly used references. If an object has a strong reference, the garbage collector will never reclaim it

Strong reference features:

  • Strong references allow direct access to the target object
  • The garbage collector will never collect as long as a reference variable exists. The JVM does not reclaim the object to which the strong reference points even if it throws an OOM exception.
  • Strong references can cause memory leak problems

Soft references

Can through the Java. Lang. Ref. SoftReference class implements a soft reference. Before the system runs out of memory, these objects are listed in the collection range for a second collection.

An object that holds a soft reference is not quickly recycled by the JVM, which determines when to recycle based on the current heap usage.

When the heap usage reaches the threshold, the objects that are soft-referenced are recycled.

Soft reference is mainly used to implement functions similar to cache. When the memory is sufficient, the value can be directly evaluated by soft reference, which improves the speed without querying data from busy real sources.

When memory is low, this cached data is automatically deleted and queried from the real source. Using soft references prevents memory leaks and makes your program more robust.

A weak reference

In Java, you can use Java. Lang. Ref. The WeakReference instances to save a weak reference of a Java object.

During system GC, objects are reclaimed regardless of whether the system heap space is sufficient.

Phantom reference

Virtual references can be implemented through the PhantomReference class. There is no way to get an instance of an object through a virtual reference, and the only purpose of setting a virtual reference association for an object is to receive a system notification when the object is reclaimed by the collector.

An object with a virtual reference is almost the same as an object without a reference and can be collected by the garbage collector at any time.

Its purpose is to detect whether an object has been removed from memory and track the garbage collection process.

Garbage collection algorithm

Mark clearance

Mark removal is the most basic collection algorithm, which is divided into “mark” and “clear” two stages:

Firstly, mark the objects that need to be recycled, and uniformly recycle the marked objects after the completion of marking. Its marking process is actually the marking process of judging garbage objects in the previous reachability analysis algorithm.

  • Before recycling:

  • After the recovery:

Disadvantages:

  • Labeling and scavenging are inefficient
  • A large number of discrete memory fragments are generated after the tag is cleared, and too much space fragment may cause not enough contiguous memory to be found when larger objects need to be allocated and another garbage collection operation has to be triggered.

Replication algorithm

It divides the memory into two equal pieces according to the capacity, and only uses one piece each time. When this piece of memory is used up, it copies the returned objects to another piece of memory, and then clears up the used memory space.

Advantages:

  • Only one piece of memory is reclaimed at a time, running efficiently
  • Simply move the pointer to the top of the stack and allocate memory in sequence, easy to implement
  • Memory reclamation does not consider the occurrence of memory fragmentation

Disadvantages:

  • The amount of memory that can be allocated at a time is reduced by half
  • Reduced space utilization

Because most new generation objects don’t survive the first GC. So there’s no need to divide the space 1 to 1. You can split a larger Eden space and two smaller Survivor Spaces, using the Eden space and one Survivor at a time. When recycling is done, the surviving objects in Eden and Survivor are copied to another Survivor at a time, and the Eden and Survivor space is cleaned up. The size ratio is generally 8:1:1, wasting 10% of Survivor space each time. But the question here is what if more than 10% survive? An allocation guarantee strategy is used here: the extra objects go straight into the old age.

  • Before recycling:

  • After the recovery:

Label finishing

The replication algorithm is more suitable for the new generation. In the old age, the survival rate of objects is relatively high. If more replication operations are performed, the efficiency will be lower.

In this algorithm, the marking process is the same as the marking process in the mark elimination method, and then the living object is moved to one end of memory, and then the memory beyond the end boundary is cleaned up directly.

  • Before recycling:

  • After the recovery:

Generational recycling

According to the living object divided into several memory areas, generally divided into new generation and old age. Then according to the characteristics of each age to develop the corresponding recovery algorithm.

  • In the new generation, a large number of objects will be found dead and only a small number of objects will survive each garbage collection, so the replication algorithm can be used to complete the collection
  • In the old days, because the object has a high survival rate and there is no extra space to allocate it, it must be recycled using mark-sweep or mark-collation algorithms