JAVA 各种reference和垃圾回收机制

java中的各种reference.
一共分为以下几种:
1. 强引用
2. 软引用 SoftReference
3. 弱引用 WeakReference
4. 虚引用 PhantomReference

5. FinalReference 所有实现finalize()方法的对象
一下是Oracle JDK. IBM的JDK会有些不同。
强引用

  1. String a = new String(“A”);

一般程序都在使用。申请太多时,会有OutOfMemory异常。gc不会自动释放。

软引用

  1. SoftReference<String> a = new SoftReference<String>(new String(“A”));
  2. String real = a.get(); // if memory is near/equal to threshold of memory, real may be null.

gc自动释放。不会有OutOfMemory异常,但是在垃圾回收之前/finalize()之前就会放入到引用队列 ReferenceQueue.
适合作为cache.

弱引用

  1. WeakReference<String> a = new WeakReference<String>(new String(“A”));
  2. String real = a.get(); // may null

gc自动释放。不会有OutOfMemory异常,但是在垃圾回收之前/finalize()之前就会放入到引用队列 ReferenceQueue.
适合作为Cache, 并且这里的意思为:如果能在内存中看到这个cache对象最好,看不到,load这个对象也不会损失很多效率。

虚引用:

  1. PhantomReference<String> a = new PhantomReference<String>(new String(“A”));
  2. String real = a.get(); // is always null

gc不会自动释放, 会有OutOfMemory。对象在垃圾回收/finalize()之后才会放入到ReferenceQueue中。这里会保证对象不会再次引用。也可以用于判断该对象是否已经从内存中移除。

FinalReference:
其实不能直接使用。这个的子类 Finalizer也不能直接使用。系统会在运行时启动FinalizerThread。 这个Thread用于清理ReferenceQueue中的对象。首先调用该对象finalize()方法,然后将引用赋值为null. 这样就解除了引用和对象的关系。这里的ReferenceQueue可以看做是以上各个引用都被最终放入到的queue对象。因为所有对象都有finalize()方法。

另外垃圾回收有两步,第一步确定垃圾回收的对象,第二步调用finalize()方法,将对象从内存中移除。在finalize()方法调用前,强引用是可以召回对象,使对象不会移除内存。这样会导致垃圾回收会反反复复回收多次,仍未能将该对象移除。但是如果使用虚引用,就能确保,进入ReferenceQueue中的引用,其对象一定已经移除内存。

参考:
http://www.ibm.com/developerworks/cn/java/j-lo-langref/
https://weblogs.java.net/blog/2006/05/04/understanding-weak-references
http://yangguangfu.iteye.com/blog/849317

标签