In Java, its memory management consists of two aspects: memory allocation (when creating Java objects) and memory recycling, both of which are done automatically by the JVM, which reduces the learning difficulty of Java programmers and avoids the danger of direct manipulation of memory like C + + +. However, because memory management is entirely the responsibility of the JVM, many programmers in Java are no longer concerned with memory allocation, causing many programs to be inefficient and consume memory. As a result, Java programmers should finally be able to understand the JVM in order to write programs that are more efficient and take full advantage of limited memory.
1.Java in-memory state
First, let's write a code for an example:
Person.java
12345678910111213141516171819 |
1
package
test;
2
3
import
java.io.Serializable;
4
5
public
class
Person
implements
Serializable {
6
7
static
final
long
serialVersionUID = 1L;
8
9
String name;
// 姓名
10 11
Person friend;
//朋友
12
13
public
Person() {}
14
15
public
Person(String name) {
16
super
();
17
this
.name = name;
18 }
19
}
|
Test.java
123456789101112131415 |
1
package
test;
2
3
4
public
class
Test{
5
6
public
static
void main(String[] args) {
7
Person p1 =
new
Person(
"Kevin"
);
8
Person p2 =
new
Person(
"Rain"
);
9
Person p3 =
new
Person(
"Sunny"
);
10
11
p1.friend = p2;
12
p3 = p2;
13
p2 =
null
;
14
}
15
}
|
The object reference in the main aspect of the above Test.java is drawn as an object reference graph that starts with the main method (vertices are objects and references, and there is a reference relationship to the edge):
When the program is running, it can be divided into three types after the state of the memory is considered as a forward graph:
1) up to state: After an object is created, there is more than one reference variable referencing it. In a graph, you can navigate from the starting vertex to the object, and it will be in the reach state.
2) Recoverable state: If an object in the program no longer has any reference variable referencing it, it will first enter the recoverable state, at which point the starting vertex of the graph can no longer navigate to the object. In this state, the system's garbage collection mechanism prepares to reclaim the memory used by the object, and the system calls the Finalize () method to clean up the resource before it is reclaimed, and if the resource is collated and re-allows more than one reference variable to refer to the object, the object becomes reachable again. Otherwise it will enter the unreachable state.
3) Unreachable state: When all associations of an object are cut off, and the system calls the Finalize () method to clean up the resource without making the object reachable, the object will permanently lose its reference and become unreachable, and the system will actually reclaim the resources that the object occupies.
The conversion diagram of the above three states is as follows:
2.Java 4 references to an object
1) Strong reference: Create an object and assign the object directly to a variable, eg:person person = new Person ("Sunny"); No matter how nervous the system resources are, the strongly quoted objects will never be recycled, even if they are not used in the future.
2) Soft reference: implemented by the SoftReference class,eg:softreference<person> p = new softreference<person> (New person ("Rain")); When the memory is very tense, it will be recycled, other times it will not be recycled, so it is important to determine if it is null before use to determine if he has been recycled.
3) Weak reference:,eg:weakreference<person> p = new weakreference<person> (New person ("Rain") is implemented through the WeakReference class; The system garbage collection must be recycled, regardless of the memory adequacy.
4) Virtual reference: cannot be used alone, it is mainly used to track the state of the object being garbage collected. By using the Phantomreference class and the reference queue Referencequeue class for federated use implementations, eg:
12345678910111213141516171819202122232425262728 |
1
package
test;
2
3
import
java.lang.ref.PhantomReference;
4
import
java.lang.ref.ReferenceQueue;
5
6
7
public class
Test{
8
9
public
static
void
main(String[] args) {
10
//创建一个对象
11
Person person =
new
Person(
"Sunny"
);
12 //创建一个引用队列
13
ReferenceQueue<Person> rq =
new
ReferenceQueue<Person>();
14
//创建一个虚引用,让此虚引用引用到person对象
15
PhantomReference<Person> pr =
new
PhantomReference<Person>(person, rq);
16
//切断person引用变量和对象的引用
17 person =
null
;
18
//试图取出虚引用所引用的对象
19
//发现程序并不能通过虚引用访问被引用对象,所以此处输出为null
20
System.out.println(pr.get());
21
//强制垃圾回收
22
System.gc();
23
System.runFinalization();
24 //因为一旦虚引用中的对象被回收后,该虚引用就会进入引用队列中
25
//所以用队列中最先进入队列中引用与pr进行比较,输出true
26
System.out.println(rq.poll() == pr);
27
}
28
}
|
Operation Result:
3.Java garbage collection mechanism
In fact, Java garbage collection mainly do two things: 1) Memory recycling 2) defragmentation
3.1 Garbage collection algorithm
1) Serial recovery (one CPU only) and parallel recycle (multiple CPUs are used): Serial recycling is a garbage collection operation with only one CPU, regardless of the number of CPUs in the system, and parallel recycling is splitting the entire collection into multiple parts, each of which is the responsibility of the CPU, This allows multiple CPUs to be recycled in parallel. Parallel recovery is highly efficient, but the complexity increases, and there are some side effects, such as increased memory fragmentation.
2) Concurrent execution and application stop: Application Stop (Stop-the-world) as the name implies, its garbage collection, while performing garbage collection, can cause the application to pause. Concurrent garbage collection does not cause application pauses, but because concurrent garbage execution requires resolution and application execution conflicts (applications may modify objects during garbage collection), the overhead of concurrently performing garbage collection is higher than Stop-the-world. And more heap memory is required for execution.
3) Compress and do not compress and copy:
① support for the compressed garbage collector (Tag-compression = Mark Clear + compress) will move all the available objects to one end, and then directly clean out the memory outside the end boundary, reducing memory fragmentation.
② non-compressed garbage collector (mark-clear) to traverse two times, the first time from the start to access all reachable objects, and mark them as reachable, the second time to facilitate the entire memory area, the unmarked state of the object to be recycled. This method of recycling is not compressed and requires no additional memory, but it takes two traversal to produce fragmentation
③ Copy garbage collector: divides the heap memory into two identical spaces, starting from the root (similar to the preceding graph start vertex) and accessing each associated reachable object, copying all reachable objects of space A to space B, and then reclaiming space a once. For this algorithm, because only access to all reachable objects, all of the objects can be copied away from the entire space directly, regardless of the unreachable object, so the cost of traversing space is small, but the need for huge replication costs and more memory.
3.2 Heap of Memory collection 1) The basis of generational recovery:
① the duration of the object's lifetime: Most objects are recycled during young
② different generation of garbage collection Strategies: New (short-lived) old (long-lived) objects rarely exist between references
2) The generation of heap memory:
①young Generation:
Ⅰ recovery mechanism: replication is used because the number of objects is small.
Ⅱ consists of 1 Eden and 2 survivor districts, two survivor zones at the same time, one for saving objects, the other is empty, and every time a young generation garbage collection is made, the objects in the Eden,from are copied to the to area. Some long-lived to replicate to the old age, and then clear the Eden,from space, and finally the original to space into from space, the original from space into to space.
Ⅲ Object Source: Most objects are first assigned to the Eden area, and some large objects are assigned directly to the old generation.
Ⅳ Recovery frequency: Because the majority of Young's objects quickly enter the unreachable state, so the recovery frequency is high and the recovery rate is fast
②old Generation:
Ⅰ recovery mechanism: Using the tag compression algorithm to recover.
Ⅱ Object Source: 1. The object goes into the old age very directly.
Long-lived objects in the 2.Young generation
Ⅲ Recovery frequency: Because very few objects die, so the frequency of execution is not high, and it takes a long time to complete.
③permanent Generation:
Ⅰ use: Used to load class, method and other information, the default is 64M, will not be recycled
Ⅱ object Source: Eg: for frameworks like hibernate,spring that like AOP dynamically generated classes, a lot of dynamic proxy classes are generated, so more permanent memory is needed. So we often encounter Java.lang.OutOfMemoryError:PermGen space error when debugging hibernate,spring, which is the error caused by the memory exhaustion of permanent generation.
Ⅲ Recovery frequency: will not be recycled
3.3 Common garbage collector
Before we do that, let's talk about the following two-word explanations of concurrency and parallelism:
1) Parallel: Refers to multiple garbage collection threads working in parallel, but at this point the user thread is still in the waiting state;
2) Concurrency: The user thread executes concurrently with the garbage collection thread (but not necessarily in parallel, possibly alternately), the user program continues to execute, and the garbage collector runs on the other CPU.
All right, keep talking. Garbage collector:
1) Serial collector (only one CPU is used): Young generation adopts serial copy algorithm, old generation uses serial tag compression algorithm (three stages: Mark mark-clears sweep-Compact compact), the program generates a pause during recycling,
2) Parallel collector: For Young's algorithm and serial collector, just add multi-CPU parallel processing, the old generation of processing and serial collector exactly the same, is still a single thread.
3) Parallel compression collector: The same algorithm is used for Young's processing, which is identical to that of the parallel collector; only the different algorithms are used for the old generation, in fact, they are divided into different regions, then the tag compression algorithm:
① the old generation into several fixed regions;
②mark stage (multi-threaded parallel), labeled to reach the object;
③summary stage (serial execution), starting at the far left to verify that an area that reaches a value (with a low object density) is found, the area and its right area are compressed, and the left end is dense area
④compact phase (multi-threaded parallel), identify the areas that need to be filled, multithreaded parallel to the data copied into these areas. After this process, there are a large number of active objects at one end of the old generation and large space on the other end.
4) Concurrent Identity-cleanup Recycle (CMS): For Young's processing, the algorithm is identical to that of the parallel collector; only different algorithms are used for the old generation, but the final place is the tag cleanup algorithm:
① Initial identification (program pause): Tags The object that is directly referenced (first-level object);
② concurrency Identifier (program run): Find other accessible objects through the first level object;
③ re-tagging (program pause): Multi-threaded parallel re-tagging of objects that may have been missed because of concurrency (simply to prevent omission)
④ Concurrency Cleanup (program run)
4. Memory Management Tips
1) Try to use direct amount, eg:string javastr = "The growth course of small apprentice";
2) Use StringBuilder and StringBuffer for string connection operation;
3) Release useless objects as soon as possible;
4) Use as few static variables as possible;
5) cache commonly used objects: can use open source open source cache implementation, Eg:oscache,ehcache;
6) Try not to use the Finalize () method;
7) When necessary, consider using soft reference softreference.
The memory recycling mechanism of Java