background
I always thought I was familiar with the four references in Java, until some time ago when a colleague checked the young GC problem and changed a local cache data from WeakReference to SoftReference to solve the young GC problem. I just realized that I didn’t fully understand the reference in 4.
Introduction to four Java references
The purpose of the four references introduced in Java is to allow the program to determine the life cycle of the object, and the JVM uses the garbage collector to treat these four references differently to change the life cycle of the object.
1. StrongReference
Strong references are the most common in Java, and if an object has a strong reference, the garbage collector will throw OOM rather than reclaim the strong reference. Such as:
Object object = new Object();Copy the code
Object is a strong reference.
2. SoftReference
If an object holds only soft references and has enough memory, the garbage collector will not reclaim it; However, if the memory space is insufficient, the memory of these objects is reclaimed. Such as:
SoftReference<Object> softReference = new SoftReference<Object>(new Object());Copy the code
SoftReference is a softReference.
Application scenario: Used for local cache.
For example, SoftCache in Mybatis is in softReference mode. If the local memory is insufficient, objects in the cache will be reclaimed.
3. WeakReference
If an object holds only weak references, when garbage collection occurs, the weak references will be collected regardless of whether memory is sufficient.
WeakReference<Object> weakReference = new WeakReference<Object>(new Object());Copy the code
WeakReference is a weakReference.
Application scenario: There are a lot of references that say it can be used for local caching, but I think it can have GC side effects (you’ll see after we talk about weak references for GC).
Example: JDK ThreadLocal is the use of WeakReference, is to prevent users forget to call remove, memory leakage.
4. Virtual Reference
Virtual references do not change the life cycle of an object; if an object holds only virtual references, it is as good as no references at all.
Application scenarios: Used to track when objects are reclaimed, for example, to prevent resource leakage. The application scenario is similar to Finalize, but it is a lighter and better mechanism than Finalizer.
Example: The DirectByteBuffer object is associated with a PhantomReference (Cleaner) when created. In this subclass, the Unsafe free interface is called to free DirectByteBuffer’s out-of-heap memory block.
The relationship between references and GC
The relationship between references and GC is shown below:
Reference types |
GC recovery time |
Time to live |
---|---|---|
Strong reference |
never |
Live until the JVM stops running |
Soft references |
Out of memory |
Terminates when out of memory |
A weak reference |
When the GC |
Terminated after GC |
Phantom reference |
unknown |
unknown |
For soft references, GC is only affected if memory is out, and GC processing looks like this:
GC () {
If (out of memory) {
Processing and recycling soft reference memory.
}
}
But for weak references, you need to deal with weak references every time you GC. GC processing looks like this:
GC () {
Weak reference memory is processed and reclaimed.
}
It usually takes two GCS to process and reclaim a reference, adding the reference to the queue on the first GC. The object is actually reclaimed during the second GC. The process is similar to finalize method.
A similar process applies to virtual references. Typical links in the mysql driver USES the ConnectionPhantomReference track link leak problem, but it can also lead to skyrocketing GC time.
How do I solve the GC elevation problem caused by references
In general, both the Young and CMS GC will show the reference processing time in the GC log. For example, the CMS GC is as follows:
If we find that the processing takes too long, we can do this by adding the argument -xx :+PrintReferenceGC. To determine which reference takes too long to process. Then dump the heap memory, use MAT to find the relevant references, and locate the problem in the code.
If there is no way to optimize at the code level, you can speed up reference processing by adding the -xx :+ParallelRefProcEnabled parameter.
conclusion
That is, in general, soft references do not affect GC (only when memory is low), but weak references can be highly visible to GC, causing GC to rise. Therefore, in the case of local cache, use weak references to minimize the impact on GC.