1. 程式人生 > >引用與垃圾回收

引用與垃圾回收

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:

  1. 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.
  2. Soft references can be deleted from a container if the clients are no longer referencing them and memory is tight.
  3. Weak references are automatically deleted from a container as soon clients stop referencing them.
  4. 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