JAVA 各种reference和垃圾回收机制

来源:互联网 发布:mysql修改表名 编辑:程序博客网 时间:2024/04/27 16:25
今天好好学习了一下java中的各种reference.
一共分为以下几种:
1. 强引用 
2. 软引用 SoftReference
3. 弱引用 WeakReference
4. 虚引用 PhantomReference

5. FinalReference 所有实现finalize()方法的对象
一下是Oracle JDK. IBM的JDK会有些不同。
强引用
String a = new String("A");
一般程序都在使用。申请太多时,会有OutOfMemory异常。gc不会自动释放。

软引用
SoftReference<String> a = new SoftReference<String>(new String("A"));String real = a.get(); // if memory is near/equal to threshold of memory, real may be null.
gc自动释放。不会有OutOfMemory异常,但是在垃圾回收之前/finalize()之前就会放入到引用队列 ReferenceQueue.
适合作为cache.

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

虚引用:
PhantomReference<String> a = new PhantomReference<String>(new String("A"));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
原创粉丝点击