引用与垃圾回收
reference /'refərəns/
an indicator that orients you generally
java.lang.ref.Reference<T>
Abstract base class for reference objects. This class defines the operations common to all reference objects. Because reference objects are implemented in close cooperation with the garbage collector, this class may not be subclassed directly.
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import java.lang.ref.PhantomReference; import java.lang.ref.ReferenceQueue; import java.lang.ref.SoftReference; import java.lang.ref.WeakReference; import org.junit.Test; public class ReferenceTest { @Test public void strongReference() { Dog ref0 = new Dog("oooo"); // 加入新引用 Dog ref1 = ref0; // 断开ref0 ref0 = null; System.gc(); assertNotNull(ref1.getName()); } /** * -Xmx32m */ @Test public void softReferenceCase1() { // 占用过半内存 byte[] ref0 = new byte[1024 * 1024 * 17]; // 加入新引用(soft) SoftReference<byte[]> ref1 = new SoftReference<byte[]>(ref0); // 断开ref0 ref0 = null; // 如果内存不够用,则ref1 被回收 byte[] ref2 = new byte[1024 * 1024 * 17]; assertNull(ref1.get()); assertNotNull(ref2); } @Test public void softReferenceCase2() { Dog ref0 = new Dog("dddd"); // 加入新引用(soft) SoftReference<Dog> ref1 = new SoftReference<Dog>(ref0); // 断开ref0 ref0 = null; System.gc(); System.gc(); assertNotNull(ref1.get().getName()); } @Test public void weakReferenceCase1() { Dog ref0 = new Dog("ssss"); // 加入新引用(weak) WeakReference<Object> ref1 = new WeakReference<Object>(ref0); // 断开ref0 ref0 = null; System.gc(); assertNull(ref1.get()); } @Test public void weakReferenceCase2() { Dog ref0 = new Dog("gggg"); // 加入新引用(weak) WeakReference<Dog> ref1 = new WeakReference<Dog>(ref0); System.gc(); // 存在强引用无法回收 assertNotNull(ref1.get()); // 断开ref0 ref0 = null; System.gc(); assertNull(ref1.get()); } @Test public void phantomReference() { Object ref0 = new Object(); // 加入新引用(phantom) ReferenceQueue<Object> queue = new ReferenceQueue<Object>(); PhantomReference<Object> ref1 = new PhantomReference<Object>(ref0, queue); // this method always returns null. assertNull(ref1.get()); } class Dog { private String name; public Dog(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } } }
Java has four orders of strength in holding onto Objects. In descending order from strongest to weakest they are:
- The JVM (Java Virtual Machine) holds onto regular Objects until they are no longer reachable by either clients or any container. In other words Objects are garbage collected when there are no more live references to them. Dead references don’t count.
- Soft references can be deleted from a container if the clients are no longer referencing them and memory is tight.
- Weak references are automatically deleted from a container as soon clients stop referencing them.
- Phantom references point to objects that are already dead and have been finalised.
Soft vs Weak vs Phantom References | ||||
---|---|---|---|---|
Type | Purpose | Use | When GCed | Implementing Class |
Strong Reference | An ordinary reference. Keeps objects alive as long as they are referenced. | normal reference. | Any object not pointed to can be reclaimed. | default |
Soft Reference | Keeps objects alive provided there’s enough memory. | to keep objects alive even after clients have removed their references (memory-sensitive caches), in case clients start asking for them again by key. | After a first gc pass, the JVMdecides it still needs to reclaim more space. | java.lang.ref.SoftReference |
Weak Reference | Keeps objects alive only while they’re in use (reachable) by clients. | Containers that automatically delete objects no longer in use. | After gc determines the object is only weakly reachable | java.lang.ref.WeakReference java.util.WeakHashMap |
Phantom Reference | Lets you clean up after finalization but before the space is reclaimed (replaces or augments the use of finalize()) | Special clean up processing | After finalization. | java.lang.ref.PhantomReference |
http://mindprod.com/jgloss/weak.html