Java语言的垃圾回收机制

    java语言从诞生开始,一个吸引人眼球的功能就是垃圾回收,想一想C++中时不时的内存泄漏,当时感觉写java代码直是一种享受呀。
    和.NET的引用计数不同,java的垃圾回收机制采取的是有向图的方式来实现,具体的说,java程序中的每个线程对象就可以看作是一个有向图的起点,有向边从栈中的引用者指向堆中的引用对象。在这个有向图中,如果一个对象和根节点之间是可达的,那么这个对象就是有效的,反之,这个对象就是可以被回收的。采取这样一种机制的优点是可以有效的避免循环引用。
    java语言中的对象引用分为以下几种:强引用、软引用、弱引用和虚引用。
    强引用就是我们经常用到的引用,这种引用在对象被标识为无效后,不会被立刻回收,除非写o = null;这种语句。
    软引用,如果一个被软引用的对象被标识为无效后,在内存控件足够的情况下,不会被回收,在内存紧张的情况下,会被回收的。
    弱引用,如果一个被弱引用的对象被标识为无效,那么对象会被立刻回收。
    虚引用,这是一种不太真实可用的引用类型,它的主要用途是结合引用关联队列,实现对对象引用关系的跟踪。
    四种引用的Sample如下:
   
Reference Sample

    执行结果如下:
Create Strong Refence: Hard_0
Create Strong Refence: Hard_1
Create Strong Refence: Hard_2
Create Strong Refence: Hard_3
Create Strong Refence: Hard_4
Create Strong Refence: Hard_5
Create Strong Refence: Hard_6
Create Strong Refence: Hard_7
Create Strong Refence: Hard_8
Create Strong Refence: Hard_9


Create Soft Refence: java.lang.ref.SoftReference@1270b73
Create Soft Refence: java.lang.ref.SoftReference@60aeb0
Create Soft Refence: java.lang.ref.SoftReference@16caf43
Create Soft Refence: java.lang.ref.SoftReference@66848c
Create Soft Refence: java.lang.ref.SoftReference@8813f2
Create Soft Refence: java.lang.ref.SoftReference@1d58aae
Create Soft Refence: java.lang.ref.SoftReference@83cc67
Create Soft Refence: java.lang.ref.SoftReference@e09713
Create Soft Refence: java.lang.ref.SoftReference@de6f34
Create Soft Refence: java.lang.ref.SoftReference@156ee8e


Create Weak Refence: java.lang.ref.WeakReference@e0e1c6
Create Weak Refence: java.lang.ref.WeakReference@6ca1c
Create Weak Refence: java.lang.ref.WeakReference@1bf216a
Create Weak Refence: java.lang.ref.WeakReference@12ac982
Create Weak Refence: java.lang.ref.WeakReference@1389e4
Create Weak Refence: java.lang.ref.WeakReference@c20e24
Create Weak Refence: java.lang.ref.WeakReference@2e7263
Create Weak Refence: java.lang.ref.WeakReference@157f0dc
Create Weak Refence: java.lang.ref.WeakReference@863399
Create Weak Refence: java.lang.ref.WeakReference@a59698


Create Phantom Refence: java.lang.ref.PhantomReference@5740bb
Create Phantom Refence: java.lang.ref.PhantomReference@5ac072
Create Phantom Refence: java.lang.ref.PhantomReference@109a4c
Create Phantom Refence: java.lang.ref.PhantomReference@201f9
Create Phantom Refence: java.lang.ref.PhantomReference@1cf8583
Create Phantom Refence: java.lang.ref.PhantomReference@14693c7
Create Phantom Refence: java.lang.ref.PhantomReference@901887
Create Phantom Refence: java.lang.ref.PhantomReference@3a6727
Create Phantom Refence: java.lang.ref.PhantomReference@4a65e0
Create Phantom Refence: java.lang.ref.PhantomReference@665753


Object Collect: Phantom_6
Object Collect: Phantom_9
Object Collect: Phantom_8
Object Collect: Phantom_7
Object Collect: Phantom_5
Object Collect: Phantom_4
Object Collect: Phantom_3
Object Collect: Phantom_2
Object Collect: Phantom_1
Object Collect: Phantom_0
Object Collect: Weak_9
Object Collect: Weak_8
Object Collect: Weak_7
Object Collect: Weak_6
Object Collect: Weak_5
Object Collect: Weak_4
Object Collect: Weak_3
Object Collect: Weak_2
Object Collect: Weak_1
Object Collect: Weak_0


虽然java语言采取了比.NET更好的垃圾回收机制,但是它也存在内存泄漏的时候,考虑以下情况:
1 Vector v = new Vector(10);
2 for (int i = 0; i < 10; i++) {
3     object o = new object();
4     v.add(o);
5     o = null;
6 }
对于每次建立的对象o,虽然最后通过o = null;语句来表明它是无效的,但是我们可以通过Vector来引用到它,这样,如果在Vector使用完毕后没有被显示的释放,即没有v = null;的话,这里就产生了内存泄漏。



参考文献:
《深入浅出JDK6.0》涂传滨 著

posted @ 2008-04-22 19:30  李潘  阅读(2202)  评论(0编辑  收藏  举报