Reference types in Java
Why are there so many middle reference types designed in the JDK?
First of all, Java is a language with its own GC, which means we don’t have to manage memory manually like C++ does. Java automatically cleans up unwanted objects, but then we have no control over the life cycle of objects.
There are a large number of objects in the system, with varying degrees of importance and life cycles. Therefore, we can use different reference types to control when the GC collects objects.
Objects can remain in memory when there is enough space; Memory space is still tight after garbage collection, and some objects can be discarded to free up memory.
After JDK 1.2, Java classifies reference objects into the following categories: the weaker the reference type from top to bottom:
- Strong Reference
- Soft Reference
- Week Reference (weak Reference)
- Phantom Reference
Java. Lang. Ref package structure:
ReferenceQueue
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.HashMap;
public class Main {
public static void main(String[] args) {
ReferenceQueue<Integer[]> queue = new ReferenceQueue<>();
// Generate large objects so that GC cleans up the objects
new Thread(() -> {
HashMap<WeakReference<Integer[]>, Integer> map = new HashMap<>();
for (int i = 0; i < 10000; i++) {
map.put(new WeakReference<>(new Integer[1024 * 1024], queue), i);
}
}).start();
// Monitor the cleaned object, at this point the object has been cleaned, only the WeakReference reference is left
new Thread(() -> {
Reference<? extends Integer[]> ref;
while (true) {
try {
while((ref = queue.remove()) ! =null) {
System.out.printf("Object reference: %s, object: %s\n", ref, ref.get()); }}catch(InterruptedException e) { e.printStackTrace(); } } }).start(); }}Copy the code
When the referenced object is cleared, the Reference(Week, Soft, Phantom) used to wrap the object is passed to the ReferenceQueue, which can then be retrieved from the queue for subsequent processing, such as determining whether a memory leak has occurred.
StrongReference
public class Main {
public static void main(String[] args) {
Object o = newObject(); }}Copy the code
When we create a new object using new, = is a strong reference, and GC will not clear the referenced object as long as the reference relationship exists.
SoftReference
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
public class Main {
public static void main(String[] args) {
ReferenceQueue<Object> refQ = new ReferenceQueue<>();
Object o = new Object();
// Create a soft reference to object o
SoftReference<Object> refOne = new SoftReference<>(o);
// Create a soft reference to object O and pass it to the ReferenceQueue, which will be passed to the queue when cleared
SoftReference<Object> refTwo = newSoftReference<>(o, refQ); }}Copy the code
Soft references are used to describe objects that are useful, but not required.
All soft references to soft reachable objects are guaranteed to be cleared before the virtual machine throws an OutOfMemoryError.
As long as the reference to the soft reference is strongly reachable (the object has a strong reference chain at this time), that is, it is actually in use, the soft reference will not be purged.
import java.lang.ref.SoftReference;
public class Main {
public static void main(String[] args) {
Object o = new Object();
SoftReference<Object> refOne = new SoftReference<>(o);
// The object o has a strong reference and is therefore strongly reachableObject otherO = o; }}Copy the code
WeakReference
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
public class Main {
public static void main(String[] args) {
ReferenceQueue<Object> refQ = new ReferenceQueue<>();
Object o = new Object();
WeakReference<Object> refOne = new WeakReference<>(o);
WeakReference<Object> refTwo = newWeakReference<>(o, refQ); }}Copy the code
Weak references describe objects that are not required, but are weaker than SoftReference. Objects containing only weak reference chains will be purged during the next GC regardless of current memory availability.
PhantomReference
import java.lang.ref.PhantomReference;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
public class Main {
public static void main(String[] args) throws InterruptedException {
ReferenceQueue<Object> refQ = new ReferenceQueue<>();
Object o = new Object();
PhantomReference<Object> ref = new PhantomReference<>(o, refQ);
The GC / / proposal
o = null;
System.gc();
// Wait to get objects cleared by GC
Reference<?> reference = refQ.remove();
System.out.println(ref);
System.out.println(reference);
}
}
// answer
java.lang.ref.PhantomReference@59a6e353
java.lang.ref.PhantomReference@59a6e353
Copy the code
It can also be called phantom reference or phantom reference, the weakest kind of reference relationship.
The existence or absence of a virtual reference does not affect its life cycle and the object instance cannot be obtained.
The only function is to receive notification from the system when the object is cleared.
Four kinds of reference comparison
Reference types | Remove time |
---|---|
StrongReference | The strong reference relationship ends |
SoftReference | Memory is insufficient |
WeakReference | At the next GC |
PhantomReference | There is no |