Geek headline users, please click "Read the original", read the original text after the typesetting
The memory model of the Java Virtual machine is divided into five parts, namely: Program counter, Java Virtual machine stack, local method stack, heap, method area.
Since these five regions are storage spaces, in order to avoid the memory full of the Java Virtual machine during runtime, it is necessary to have a garbage collector's role, and periodically reclaim some invalid memory to ensure that the Java Virtual machine can continue to run healthily.
This garbage collector is what we call the "garbage collector", so when does the garbage collector clean up the memory? What data is cleaned? That's the problem we're going to solve next.
program counters, Java Virtual machine stacks, and local method stacks are thread-private, that is, each thread owns the three blocks, and it is created as the thread is created and destroyed by the end of the thread. The question of when the garbage collector cleans the three areas is solved.
In addition, the stack frames in the Java Virtual machine stack and the local method stack are stacked with the beginning of the method, the end of the method is stacked, and the local variable table in each stack frame is determined when the class is loaded. Therefore, the garbage collection work in the above three regions is deterministic, and the garbage collector is able to clearly know when to clean up what data in these three areas.
However, the memory cleanup work in the heap and the method area is not that easy.
The heap and the method area are shared by all threads and are created at the start of the JVM and run until the JVM is stopped. Therefore, they cannot be created based on the creation of the thread, and the end of the thread is freed.
The heap holds all objects during the JVM's run, although the memory size of each object is determined when the object's class is loaded, but how many objects are created can only be determined during the run of the program.
The method area holds class information, static member variables, constants. A class is loaded when the program is running, and the class is loaded when it is necessary to create an object of that class. Therefore, how many classes the JVM will load will also need to be determined during the run of the program.
Therefore, the memory reclamation of the heap and the method area is nondeterministic, so the garbage collector spends a bit of time reclaiming the heap and the method area memory.
Recovery of heap memory 1. How do I determine which objects need to be recycled?
Before objects are reclaimed from the heap, it is first to determine which are invalid objects. We know that an object that is not referenced by any object or variable is an invalid object and needs to be recycled. Generally there are two ways of judging:
Reference counting method
Each object has a counter that, when referenced by a variable or another object, adds one to the counter, or minus one if the reference fails. When the counter is 0 o'clock, the object is considered to be an invalid object.
The method of accessibility analysis
All objects that are directly or indirectly associated with GC roots are valid objects, and objects that are not associated with GC roots are invalid objects.
GC roots refers to the following:
- The object referenced by the Java Virtual machine stack (the object referenced by a variable of the reference type in the local variable table in the stack frame)
- Objects referenced by static properties in the method area
- Objects referenced by constants in the method area
- Objects referenced by the local method stack
Compare the two:
The reference counting method is simple, but there is a serious problem that does not solve the problem of circular references.
Therefore, the current mainstream language uses the accessibility analysis method to determine whether the object is valid.
2. Process of retrieving invalid objects
When the JVM filters out the failed objects, it is not immediately clear, but gives the object a chance to regenerate again, as follows:
Determines whether the object overrides the Finalize () method
- If the method is overridden and the Finalize () method of the object has not been executed, then finalize () is thrown into the f-queue queue;
- If this method is not overridden, the object memory is freed directly.
Execute the Finalize () method in the F-queue queue
Virtual Opportunities Execute these finalize () methods with a lower priority and do not ensure that all the Finalize () methods will be executed at the end. If a time-consuming operation occurs in the Finalize () method, the virtual machine stops execution directly and clears the object.
Object Rebirth or death
If you assign this to a reference when you execute the Finalize () method, the object is reborn. If not, it will be purged by the garbage collector.
Note:
It is strongly not recommended to use the Finalize () function for any action! If you need to release resources, use try-finally.
Because Finalize () is large in uncertainty and overhead, it cannot guarantee smooth execution.
Memory reclamation for method areas
We know that if you use the replication algorithm to realize the heap of memory recycling, the heap will be divided into the new generation and the old age, the new generation of the object "to die", each garbage collection will erase a large number of objects, and the old age of the object life is longer, each garbage collection only a small number of objects are cleared away.
Because the method area holds long life-cycle class information, constants, and static variables, the method area is like the old age of the heap, where only a small amount of garbage is removed from each garbage collection.
Two types of garbage are mainly cleared in the method area:
1. Obsolete constants
2. Discarded classes
1. How to determine the obsolete constants?
Clearing obsolete constants is similar to clearing objects, so long as constants in a constant pool are not referenced by any variables or objects, the constants are erased.
2. How to discard discarded classes?
The conditions for clearing obsolete classes are more stringent:
1. All objects of this class have been cleared
2. The Java.lang.Class object of this class is not referenced by any object or variable
As long as a class is loaded into the method area by a virtual machine, there will be an object in the heap that represents that class: Java.lang.Class. This object is created when the class is loaded into the method area and purged when the class is deleted in the method area.
3. The classloader that loaded the class have been recycled
Garbage collection algorithm
Now that we know that an object is an invalid object, that a class is an obsolete class, and that a constant is an obsolete constant, that is, knowing what data the garbage collector will erase, then we'll show you how to clear that data.
1. Tag-Clear algorithm
First, we use the method just described to determine what data needs to be purged and mark them, and then clear the tagged data.
Analysis:
This algorithm is inefficient in marking and purging processes, and there is a lot of fragmentation space after elimination, which prevents large objects from being stored and reduces space utilization.
2. Copying algorithms
Divide the memory into two parts and store the data only on one piece. When garbage is needed, the discarded data is first marked, then the useful data is copied to another piece of memory, and the first block of memory is finally cleared.
Analysis:
This algorithm avoids the fragmentation space, but the memory is reduced by half.
And every time you need to copy all the useful data to another piece of memory, the efficiency is not high.
address Space Utilization issues:
In the Cenozoic, because a large number of objects are "dying", that is, once garbage collection only a small number of objects survived, so we can divide the memory into three pieces: Eden, Survior1, Survior2, memory size is 8:1:1. When allocating memory, only Eden and a piece of Survior1 are used. When Eden+survior1 memory is found to be full, the JVM initiates a MINORGC, clears out the discarded objects, and copies all surviving objects to another Survior2. Then, the memory allocation is then done using Survior2+eden.
In this way, it takes only 10% of the memory space to implement a garbage collection method with compression, which avoids the problem of memory fragmentation.
However, when an object is requesting memory space, it is found that the remaining space in the Eden+survior cannot be placed on the object, the minor GC is required, and if the memory space that is free after the MINORGC is still unable to place the object, then the object needs to be transferred to the old age. This approach is called "allotment Guarantee".
What is a distribution guarantee?
When the JVM is ready to allocate memory space for an object, it is found that the idle area in the Eden+survior cannot be mounted, and the MINORGC is triggered to reclaim the discarded objects in that area. However, if only a small number of objects are recycled after MINORGC and the new objects are still not loaded, then all objects in the Eden+survior need to be transferred to the old age before the new objects are saved in the Eden area. This process is the "allotment guarantee".
3. Labeling-Sorting algorithm
Before recycling garbage, first mark all discarded objects, then move all unmarked objects to one side, and finally empty the other side area.
Analysis:
It is an old-age garbage collection algorithm. Objects in the old age tend to have a long life span, so a large number of objects will survive each garbage collection, so if you choose the "Copy" algorithm, it can be inefficient to replicate a large number of surviving objects at a time. Moreover, using the "copy" algorithm in the Cenozoic, when an object is not in the Eden+survior, the memory of the old age can be used for "allotment guarantee", and if the algorithm is used in the old age, then in the old age if the occurrence of Eden+survior does not fit an object, There was no other area to give him the allotment guarantee. Thus, the "mark-and-tidy" algorithm is commonly used in the old age.
4. Generation of collection algorithms
Divide the memory into old and new generations. Long-lived objects in the old age, the new generation of storage "towards the death of the dead" object. Then, different garbage collection algorithms are used in different regions.
Types of references in Java
In Java, references are divided into 4 classes based on the length of the life cycle.
1. Strong references
The references we use in our usual way are strong references.
A = new A ();
The reference that is associated with the object created by the keyword new is a strong reference.
As long as a strong reference exists, the object will never be recycled.
2. Soft references
The JVM reclaims the object pointed to by the soft reference only if the heap is about to occur with an Oom exception.
Soft references are implemented through the SoftReference class.
The life cycle of a soft reference is shorter than a strong reference.
3. Weak references
As long as the garbage collector is running, the object that the soft reference points to is recycled.
Weak references are implemented through the WeakReference class.
The life cycle of a weak reference is shorter than a soft reference.
4. Virtual References
A virtual reference is also called a phantom reference, and it has no distinction with no reference, and cannot access any property or function of an object through a virtual reference.
The only purpose of an object association virtual reference is to receive a system notification before the object is reclaimed by the garbage collector.
Virtual references are implemented through the Phantomreference class.
In-depth understanding of JVM Combat (iii)--A detailed description of the garbage collection strategy