Home > Java > javaTutorial > body text

A brief analysis of Java memory model and garbage collection

高洛峰
Release: 2017-01-17 15:41:56
Original
1271 people have browsed it

1. Java memory model

When the Java virtual machine executes a program, it divides the memory it manages into several data areas. The distribution of these data areas is as shown in the figure below:

A brief analysis of Java memory model and garbage collection

Program counter: A small memory area that points to the currently executed bytecode. If the thread is executing a Java method, this counter records the address of the virtual machine bytecode instruction being executed. If a Native method is executed, the counter value is empty.

Java virtual machine stack: Thread private, its life cycle is consistent with the thread. When each method is executed, a stack frame will be created to store information such as local variable tables, operand stacks, dynamic links, method exits, etc. .

Local method stack: The function is similar to the virtual machine stack, except that the virtual machine stack serves the virtual machine to execute Java methods, while the local method stack serves the Native methods used.

Java heap: It is the largest piece of memory managed by the virtual machine and is shared by all threads. This area is used to store object instances. Almost all objects are allocated in this area. The Java heap is the main area for memory recycling. From the perspective of memory recycling, since most current collectors use generational collection algorithms, the Java heap can also be subdivided into: the new generation and the old generation. If it is further subdivided, it can be divided into Eden space, From Survivor space, To Survivor space, etc. According to the Java virtual machine specification, the Java heap can be in a physically discontinuous space, as long as it is logically continuous.

Method area: Like Java, it is shared by each thread and is used to store data such as class information loaded by the virtual machine, constant lights, static variables, and code compiled by the just-in-time compiler.

Runtime constant pool, the runtime constant pool is part of the method area. In addition to the description information such as the class version, fields, methods, interfaces, etc., the Class file also has a constant pool, which is used to Stores various literals and symbol references generated during compilation. New constants can be put into the constant pool during operation. The most commonly used method is the intern() method of the String class. When a String instance calls intern, Java searches to see if there is the same Unicode string constant in the constant pool. If there is, return its reference; if not, add a Unicode equal to the instance string in the constant pool and return its reference.

2. How to determine garbage objects

There are several object instances stored in the Java heap. Before the garbage collector recycles the heap, it first needs to determine which objects are still "alive". Which objects are "dead", that is, they will not be used in any way.

Reference counting method

The reference counting method is simple to implement and highly efficient. It is a good algorithm in most cases. The principle is: add a reference counter to the object. Whenever there is a reference to the object, the counter increases by 1. When the reference expires, the counter decreases by 1. When the counter value is 0, it means that the object is no longer used. It should be noted that the reference counting method is difficult to solve the problem of circular references between objects. The mainstream Java virtual machine does not use the reference counting method to manage memory.

Reachability Analysis Algorithm

The basic idea of ​​this algorithm is to use a series of objects called "GC Roots" as the starting point, and search downwards from these nodes to search the path. The path passed is called a reference chain. When there is no reference chain connecting an object to GC Roots (in graph theory terms, it means that the object is unreachable from GC Roots), it proves that the object is unavailable. of. As shown in the figure, although objects object 5, object 6, and object 7 are related to each other, they are not reachable from GC Roots, so they will be judged as recyclable objects.

A brief analysis of Java memory model and garbage collection

In the Java language, the objects that can be used as GC Roots include the following:

In the virtual machine stack (local variable table in the stack frame) the referenced object.

The object referenced by the class static property in the method area.

Object referenced by constants in the method area.

The object referenced by JNI (generally known as Native method) in the local method stack.

Now the question comes, will the reachability analysis algorithm cause circular reference problems between objects? The answer is yes, that is, there will be no circular reference problems between objects. GC Root is a specially defined "starting point" outside the object graph and cannot be referenced by objects in the object graph.

To Die Or Not To Die

Even in the reachability analysis algorithm, unreachable objects are not "necessary to die". At this time, they are temporarily in the "probation" stage. To truly declare an object dead, it must go through at least two marking processes. : If the object is found to have no reference chain connected to GC Roots after the reachability analysis, it will be marked for the first time and filtered once. The filtering condition is whether it is necessary to execute the finapze() method on this object. When the object does not cover the finapze() method, or the finapze() method has been called by the virtual machine, the virtual machine treats both situations as "no need to execute". The program can perform a "thrilling" self-rescue process by overriding finapze(), but this only has one chance.

/** 
 * 此代码演示了两点: 
 * 1.对象可以在被GC时自我拯救。 
 * 2.这种自救的机会只有一次,因为一个对象的finapze()方法最多只会被系统自动调用一次 
 * @author zzm 
 */
pubpc class FinapzeEscapeGC { 
  
 pubpc static FinapzeEscapeGC SAVE_HOOK = null; 
  
 pubpc void isApve() { 
  System.out.println("yes, i am still apve :)"); 
 } 
  
 @Override
 protected void finapze() throws Throwable { 
  super.finapze(); 
  System.out.println("finapze mehtod executed!"); 
  FinapzeEscapeGC.SAVE_HOOK = this; 
 } 
  
 pubpc static void main(String[] args) throws Throwable { 
  SAVE_HOOK = new FinapzeEscapeGC(); 
  
  //对象第一次成功拯救自己 
  SAVE_HOOK = null; 
  System.gc(); 
  //因为finapze方法优先级很低,所以暂停0.5秒以等待它 
  Thread.sleep(500); 
  if (SAVE_HOOK != null) { 
SAVE_HOOK.isApve(); 
  } else { 
System.out.println("no, i am dead :("); 
  } 
  
  //下面这段代码与上面的完全相同,但是这次自救却失败了 
  SAVE_HOOK = null; 
  System.gc(); 
  //因为finapze方法优先级很低,所以暂停0.5秒以等待它 
  Thread.sleep(500); 
  if (SAVE_HOOK != null) { 
SAVE_HOOK.isApve(); 
  } else { 
System.out.println("no, i am dead :("); 
  } 
 } 
}
Copy after login

The running result is:

finapze mehtod executed! 
yes, i am still apve :) 
no, i am dead :(
Copy after login

Then let’s talk about references

Whether it is judging the number of references to an object through the reference counting algorithm, or judging the references to the object through the reachability analysis algorithm Whether the chain is reachable and whether the object is alive are all related to "reference". Before JDK 1.2, the definition of reference in Java was very traditional: if the value stored in the reference type data represents the starting address of another memory, it is said that this memory represents a reference. After JDK 1.2, Java expanded the concept of references and divided references into four types: Strong Reference, Soft Reference, Weak Reference, and Phantom Reference. These four The intensity of citations gradually weakens.

• Strong references refer to references that are ubiquitous in program code, such as "Object obj = new Object()". As long as the strong references still exist, the garbage collector will never reclaim them. the referenced object.

• Soft references are used to describe some objects that are useful but not necessary. For objects associated with soft references, these objects will be included in the recycling scope for the second recycling before a memory overflow exception occurs in the system. If there is not enough memory for this recycling, a memory overflow exception will be thrown. After JDK 1.2, the SoftReference class is provided to implement soft references.

• Weak references are also used to describe non-essential objects, but their strength is weaker than soft references. Objects associated with weak references can only survive until the next garbage collection occurs. When the garbage collector works, objects associated with only weak references will be recycled regardless of whether the current memory is sufficient. After JDK 1.2, the WeakReference class is provided to implement weak references.

• Phantom reference is also called ghost reference or phantom reference. It is the weakest kind of reference relationship. Whether an object has a virtual reference has no impact on its lifetime, and it is impossible to obtain an object instance through a virtual reference. 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. After JDK 1.2, the PhantomReference class is provided to implement virtual references.

Soft reference usage example:

package jvm;
 
import java.lang.ref.SoftReference;
 
class Node {
pubpc String msg = "";
}
 
pubpc class Hello {
pubpc static void main(String[] args) {
Node node1 = new Node(); // 强引用
node1.msg = "node1";
SoftReference<Node> node2 = new SoftReference<Node>(node1); // 软引用
node2.get().msg = "node2";
 
System.out.println(node1.msg);
System.out.println(node2.get().msg);
}
}
Copy after login

The output result is:

node2
node2
Copy after login

3. Typical garbage collection algorithm

1. Mark-Sweep (mark-clear) algorithm

This is the most basic garbage collection algorithm. The reason why it is the most basic is that it is the easiest to implement and the idea is the simplest. The mark-sweep algorithm is divided into two phases: the mark phase and the clear phase. The task of the marking phase is to mark all objects that need to be recycled, and the cleanup phase is to recover the space occupied by the marked objects. The specific process is shown in the figure below:

A brief analysis of Java memory model and garbage collection

It can be easily seen from the figure that the mark-clear algorithm is relatively easy to implement, but there is a serious problem that it is easy to generate memory. Fragments. Too many fragments may cause insufficient space to be found when space for large objects needs to be allocated in the subsequent process, triggering a new garbage collection action in advance.

2. Copying algorithm

In order to solve the shortcomings of the Mark-Sweep algorithm, the Copying algorithm was proposed. It divides the available memory into two equal-sized blocks according to capacity, and only uses one of them at a time. When this block of memory is used up, copy the surviving objects to another block, and then clean up the used memory space at once, so that the problem of memory fragmentation is less likely to occur. The specific process is shown in the figure below:

A brief analysis of Java memory model and garbage collection

Although this algorithm is simple to implement, efficient in operation and not prone to memory fragmentation, it imposes a high cost on the use of memory space. The cost is that the memory that can be used is reduced to half of the original.

Obviously, the efficiency of the Copying algorithm has a great relationship with the number of surviving objects. If there are many surviving objects, the efficiency of the Copying algorithm will be greatly reduced.

3. Mark-Compact (mark-compact) algorithm

In order to solve the defects of the Copying algorithm and make full use of the memory space, the Mark-Compact algorithm is proposed. The marking phase of this algorithm is the same as Mark-Sweep, but after completing the marking, it does not directly clean up the recyclable objects, but moves the surviving objects to one end, and then cleans up the memory outside the end boundary. The specific process is shown in the figure below:

A brief analysis of Java memory model and garbage collection

4. Generational Collection (generational collection) algorithm

The generational collection algorithm is the garbage collection of most JVMs currently. algorithm used by the processor. Its core idea is to divide the memory into several different areas according to the life cycle of the object. Under normal circumstances, the heap area is divided into the Tenured Generation and the Young Generation. The characteristic of the Old Generation is that only a small number of objects need to be recycled during each garbage collection, while the characteristic of the Young Generation is that every garbage collection There are a large number of objects that need to be recycled, so the most suitable collection algorithm can be adopted according to the characteristics of different generations.

Currently, most garbage collectors adopt the Copying algorithm for the new generation, because most objects must be recovered for each garbage collection in the new generation, which means that the number of copying operations is less, but in practice it does not The space of the new generation is not divided according to the ratio of 1:1. Generally speaking, the new generation is divided into a larger Eden space and two smaller Survivor spaces (usually 8:1:1). Use Eden space and one of the Survivor spaces. When recycling, copy the surviving objects in Eden and Survivor space to another Survivor space, and then clean up Eden and the Survivor space just used.

Since the characteristic of the old generation is that only a small number of objects are recycled each time, the Mark-Compact algorithm is generally used.

The above brief analysis of Java memory model and garbage collection is all the content shared by the editor. I hope it can give you a reference, and I hope you will support the PHP Chinese website.

For more articles on Java memory model and garbage collection, please pay attention to the PHP Chinese website!

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template