Java reference types are strong, soft, weak, and virtual. They have different effects.
Strong reference
All GC Root can trace back to during basic daily development are strong references. Such as locally declared local variables. GC Root is not reachable when GC is triggered, otherwise strongly referenced objects are not collected.
Soft references
Declare a soft reference in Java that takes up 2MB of memory.
SoftReference<byte[]> softReference = new SoftReference<>(new byte[(1024*1024*2)]);
Copy the code
Conditions (or relationships) for soft reference recycling:
- GC Root is unreachable.
- When GC is still out of memory, soft-referenced objects are reclaimed.
Sample code:
//4mb SoftReference<byte[]> softReference = new SoftReference<>(new byte[(1024*1024*2)]); @test public void softReference() {// -xmx5m system.out.println (" softReference "+softReference.get()); List<byte[]> a = new ArrayList<>(); For (int I = 0; for (int I = 0; i<=1; i++) { a.add(new byte[1024*1024]); // 1mb} system.out.println (" softReference end "+ softreference.get ()); }Copy the code
Soft references are more suitable for caching scenarios because they can be conveniently cleaned up by the JVM GC without having to worry about the elimination strategy in case of insufficient memory. Note that all soft references are cleaned. After a soft reference is cleaned, the JVM does not decide whether to clean it again based on whether there is enough memory. Instead, it clears all soft references.
Phantom reference
A virtual reference can be used to listen to whether an object has been collected and can be used instead of the java.lang.Object#finalize method. We know that the java.lang.Object#finalize method is executed ina single thread after an object is judged to be garbage and before the object is known. Therefore, the use of java.lang.Object#finalize will delay the release of memory space. The use of virtual references is triggered after the object’s memory has been cleared, allowing the thread to control itself.
Sample code:
@test public void phantomReference() throws InterruptedException {system.out.println (" virtual reference "); ReferenceQueue<Object> rq = new ReferenceQueue<>(); Object o1 = new Object(); PhantomReference<Object> objectPhantomReference1 = new PhantomReference<>(o1, rq); System.out.println(objectPhantomReference1); o1 = null; System.gc(); TimeUnit.SECONDS.sleep(1); System.out.println(rq.poll()); O1 system.out.println (" phantom reference end"); }Copy the code
Virtual references are mainly used in resource release scenarios when listening objects are cleared.