In Java, its memory management includes two aspects: memory allocation (when creating Java objects) and memory recycling. Both aspects of work are automatically completed by the JVM, reducing the difficulty of learning for Java programmers and avoiding the danger of directly operating memory like C/C++. However, it is precisely because memory management is entirely handled by the JVM that many Java programmers no longer care about memory allocation, resulting in many programs being inefficient and consuming memory. Therefore, Java programmers should understand the JVM in the end in order to write more efficient programs and make full use of limited memory.
1.Java's state in memory
First, let's write a code as an example:
Person.java
package test;import java.io.Serializable;public class Person implements Serializable { static final long serialVersionUID = 1L; String name; // Name Person friend; // Friends public Person() {} public Person(String name) { super(); this.name = name; }} Test.java
package test;public class Test{ public static void main(String[] args) { Person p1 = new Person("Kevin"); Person p2 = new Person("Rain"); Person p3 = new Person("Sunny"); p1.friend = p2; p3 = p2; p2 = null; }} If you draw the object reference in the main aspect in Test.java above into an object reference diagram starting from the main method, it is like this (vertices are objects and references, and directed edges are reference relationships):
When the program runs, after it is regarded as a directed graph, it can be divided into three types:
1) Achievable state: After an object is created, more than one reference variable refers to it. In a directed graph, you can navigate to the object from the starting vertex, and it is in an accessible state.
2) Recoverable state: If an object in the program no longer has any reference variables referring to it, it will first enter the restoreable state, and at this time, it cannot navigate to the object from the starting vertex of the directed graph. In this state, the system's garbage collection mechanism is ready to recycle the memory occupied by the object. Before recycling, the system will call the finalize() method to clean up the resource. If more than one reference variable is reclaimed after the resource is sorted, the object will become an accessible state again; otherwise it will enter an unreachable state.
3) Unreachable state: When all the associations of the object are cut off and the system calls the finalize() method to clean up the resource still does not make the object reachable state, then the object will permanently lose reference and become unreachable state, and the system will truly recycle the resources occupied by the object.
The transition diagram of the above three states is as follows:
2. 4 references to objects by Java
1) Strong reference: Create an object and assign this object directly to a variable, eg: Person person = new Person("sunny"); No matter how tight the system resources are, the strong referenced object will never be recycled, even if it will not be used again in the future.
2) Soft reference: Implemented through the SoftReference class, eg: SoftReference<Person> p = new SoftReference<Person>(new Person("Rain"));, when the memory is very tight, it will be recycled, and will not be recycled at other times, so before using it, you must determine whether it is null to determine whether it has been recycled.
3) Weak reference: Implemented through the WeakReference class, eg: WeakReference<Person> p = new WeakReference<Person>(new Person("Rain")); Regardless of whether the memory is sufficient, the system will definitely be recycled during garbage collection.
4) Virtual quote: It cannot be used alone, it is mainly used to track the state of the object being garbage collected. Implemented through the PhantomReference class and the reference queue ReferenceQueue class, eg:
package test;import java.lang.ref.PhantomReference;import java.lang.ref.ReferenceQueue;public class Test{ public static void main(String[] args) { //Create an object Person person = new Person("Sunny"); //Create a reference queue ReferenceQueue<Person> rq = new ReferenceQueue<Person>(); //Create a virtual reference, let this virtual reference reference to the person object PhantomReference<Person> pr = new PhantomReference<Person>(person, rq); //Settle off the reference variables and objects of person references person = null; //Try to get out the object referenced by the virtual reference//I found that the program cannot access the referenced object through the virtual reference, so the output here is null System.out.println(pr.get()); //Forced garbage collection System.gc(); System.runFinalization(); //Because once the object in the virtual reference is recycled, the virtual reference will enter the reference queue//So use the reference first entered the queue in the queue to compare with pr, and output true System.out.println(rq.poll() == pr); }}Running results:
3. Java garbage collection mechanism
In fact, Java garbage collection mainly does two things: 1) Memory recycling 2) Defragmentation
3.1 Garbage Collecting Algorithm
1) Serial recycling (only one CPU) and parallel recycling (multiple CPUs are useful): Serial recycling means that no matter how many CPUs the system has, it is always only one CPU to perform garbage collection operations. Parallel recycling means splitting the entire recycling work into multiple parts, each part being responsible by one CPU, so that multiple CPUs can be recycled in parallel. Parallel recycling is very efficient in execution, but it increases complexity, and there are also some side effects, such as random increase in memory.
2) Concurrent execution and application stop: As the name suggests, its garbage collection method will cause application suspension while performing garbage collection. Although garbage collection of concurrent execution will not cause the application to be paused, because concurrent execution garbage needs to resolve conflicts with the application (the application may modify objects during the garbage collection process), the system overhead of concurrent execution of garbage collection is higher than that of Stop-the-world, and requires more heap memory when executing.
3) Compress and non-compress and copy:
① The garbage collector that supports compression (mark-compression = mark-clear + compression) will relocate all reachable objects together, and then recycle all the previously occupied memory, reducing memory fragmentation.
② The uncompressed garbage collector (mark-clear) needs to be traversed twice. The first time you first access all reachable objects and mark them as reachable states. The second time you facilitate the entire memory area and recycle objects that are not marked reachable states. This recycling method is not compressed and does not require extra memory, but it will produce fragmentation if it takes two traversals.
③ Copy garbage collector: divide the heap memory into two identical spaces, access each associated reachable object from the root (similar to the starting vertex of the previous directed graph), copy all reachable objects in space A to space B, and then recycle space A at one time. For this algorithm, because you only need to access all reachable objects, copy all reachable objects away, and directly recycle the entire space, ignoring the unreachable objects at all, the cost of traversing the space is small, but it requires huge copying costs and more memory.
3.2 Generational recycling of heap memory
1) The basis for generational recycling:
①The length of the object's survival time: Most objects are recycled during the Young period ② Different generations adopt different garbage recycling strategies: new (short survival time) old (long survival time) rarely have references between objects
2) Generation of heap memory:
① Young generation:
ⅠRecycling mechanism: Because the number of objects is small, replication and recycling are used.
Ⅱ Consolidation area: It consists of 1 Eden area and 2 Survivor areas. Two Survivor areas at the same time, one is used to save the object and the other is empty; every time Young generation garbage collection is carried out, the accessible objects in Eden and From are copied into the To area, and some of the long-lived ones are copied to the old age, then the Eden and From space is cleared, and finally the original To space becomes From space, and the original From space becomes To space.
Ⅲ Object Source: Most objects are assigned to the Eden area first, and some large objects will be assigned directly to the Old generation.
Ⅳ Recycling frequency: Because most Young generation objects quickly enter an unreachable state, the recycling frequency is high and the recycling speed is fast.
②Old generation:
ⅠRecycling mechanism: Use mark compression algorithm to recover.
Ⅱ Source of objects: 1. The large object directly enters the old age.
2. Recycling frequency of reachable objects with long survival time in the Young generation: Because few objects die, the execution frequency is not high and it takes a long time to complete.
③Permanent generation:
ⅠPurpose: used to load Class, method and other information. The default is 64M and will not be recycled. ⅡObject Source: eg: For frameworks like Hibernate and Spring that like AOP dynamic generation classes often generate a large number of dynamic proxy classes, so more Permanent generation memory is needed. So we often encounter java.lang.OutOfMemoryError:PermGen space error when debugging Hibernate. This is the error caused by Permanent generation memory exhaustion.
Ⅲ Recycling frequency: will not be recycled
3.3 Common garbage collectors
1) Serial recycler (only one CPU is used): Young generation uses serial copy algorithm; Old generation uses serial mark compression algorithm (three stages: mark mark - clear sweep - compress compact), the program will be paused during the recycling period.
2) Parallel Recycler: The algorithm used for the Young generation is the same as the serial recycler, but it only adds multi-CPU parallel processing; the processing of the Old generation is exactly the same as that of the serial recycler, and is still a single thread.
3) Parallel compression collector: The processing of Young generation is exactly the same algorithm as that of parallel collector; but different algorithms are used for Old generation, which is actually divided into different regions and then labeling and compression algorithm:
① Divide Old into several fixed areas;
② mark stage (multi-threaded parallel), marking reachable objects;
③ summary stage (serial execution). When you find an area that reaches the numerical value (low object density) from the left, this area and its right area are compressed and recovered. The left end is the dense area ④ compact stage (multi-thread parallel), identify the areas that need to be loaded, and copy the data into these areas in parallel. After this process, there are a large number of active objects on one end of the Old Generation, and a large piece of space on the other end.
4) Concurrent identification - Cleaning and Recycling (CMS): The processing of Young generation is exactly the same algorithm as that of parallel recyclers; but different algorithms are used for Old generation, but the mark cleaning algorithm is still used:
① Initial identification (program pause): marks the object directly referenced (first-level object);
② Concurrent identification (program run): find other reachable objects through first-level objects;
③ Re-mark (program pause): Multi-thread parallel re-marking objects that may have been missed due to concurrency (simply speaking, it is anti-missing)
④ Concurrent cleaning (program runs)
4. Memory management tips
1) Try to use direct quantity, eg: String javaStr = "the growth process of primary school apprenticeship";
2) Use StringBuilder and StringBuffer to perform string concatenation and other operations;
3) Release useless objects as soon as possible;
4) Try to use static variables as little as possible;
5) Cache commonly used objects: can be implemented using open source open source cache, eg: OSCache, Ehcache;
6) Try not to use the finalize() method;
7) You can consider using soft reference SoftReference when necessary.
The above is all the content of this article. I hope it will be helpful to everyone's learning and I hope everyone will support Wulin.com more.