`
m635674608
  • 浏览: 5027372 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

Java Reference引用 强引用 软引用 弱引用 虚引用

 
阅读更多

1,强引用:

package com.myjava.reference;

/**

  * ①强引用不会被垃圾回收器自动回收

  * ②当内存空间不足时,Java虚拟机宁可抛出OutOfMemoryError错误,也不会随意回收强引用对象来解决内存不足问题

  * @author Administrator

  *

  */

public class TestStrongReference {

public static void main(String[] args) {

Object ref = new Object();

Object strongRef = ref;

System.gc();

System.out.println(strongRef!=null?"StrongRef not gc":"StrongRef is gc");

}

}

-------------------------------------------------------------------------------------------------------------------------------

2,软引用;

package com.myjava.reference;

import java.lang.ref.SoftReference;

/**

  * ①,softReference 软引用在内存充足时不会被GC,

  * ②,当内存空间不足时就会回收这些对象的内存

  * ③,适合做高速访问,如cache--Android开发中

  * @author Administrator

  *

  */

public class TestSoftReference {

public static void main(String[] args) {

String str = "test soft GC";

SoftReference<String> softReference = new SoftReference<String>(str);

str = null;

System.gc();

System.out.println(softReference.get() != null ? "softReference not gc"

: "softReference is gc");

}

}

----------------------------------------------------------------------------------------------------------

弱引用:

package com.myjava.reference;

import java.lang.ref.WeakReference;

/**

  * ①,不管当前内存空间足够与否,都会回收它的内存。

  * ②,结合ReferenceQueue可以让程序在第一时间得到referent被回收的事件

  * ③,一般用来防止内存泄漏,要保证内存被VM回收

  * @author Administrator

  *

  */

public class TestWeakReference {

public static void main(String[] args) {

String  str  =  "test weakReference " ;  

WeakReference< String >  weakReference  =  new  WeakReference< String>(str);  

str = null;  

System.gc();  

System.out.println(weakReference.get()!= null? "weakReference not gc": "weakReference is gc");  

}

}

http://blog.csdn.net/xhh198781/article/details/6459926

http://zhangjunhd.blog.51cto.com/113473/53092/

http://blog.csdn.net/rzhzhz/article/details/7679032

-----------------------------------------------------------------------------------------------------------------

4,虚引用

package com.myjava.reference;

 

 

import java.lang.ref.PhantomReference;

import java.lang.ref.Reference;

import java.lang.ref.ReferenceQueue;

import java.util.HashMap;

 

public class TestPhantomReference {

 

   public static void main(String[] args) {

     ReferenceQueue referenceQueue = new ReferenceQueue();

     Object object = new Object() {

       public String toString() {

         return "Referenced Object";

       }

     };

 

     Object data = new Object() {

       public String toString() {

         return "Data";

       }

     };

 

     HashMap map = new HashMap();

     Reference reference = null;

     System.out.println("Testing PhantomReference.");

     reference = new PhantomReference(object, referenceQueue);

 

     map.put(reference, data);

 

     System.out.println(reference.get()); // null

     System.out.println(map.get(reference)); // Data

     System.out.println(reference.isEnqueued()); // false

 

     System.gc();

     System.out.println(reference.get()); // null

     System.out.println(map.get(reference)); // Data

     System.out.println(reference.isEnqueued()); // false

 

     object = null;

     data = null;

 

     System.gc();

     System.out.println(reference.get()); // null

     System.out.println(map.get(reference)); // Data

     System.out.println(reference.isEnqueued()); // true, because object has been reclaimed.

   }

 

}

http://www.oschina.net/question/12_8662

 

Strong Reference, 强引用,即java标准的引用方式,表示GC从 Root Set 开始向下扫描,可以找到对应的 Strong Reference。

 

Referent,被包装为 Weak, Soft, Phantom Reference的对象引用称之为 referent。后面的内容会多次提到这个名词。

 

Weak Reference, 弱引用。当一个referent,在运行时没有同时被强,软引用,只被Weak Reference自身引用,且Weak Reference从 Root Set 可达,则该referent会被GC回收。

 

WR的作用,一般是为referent提供一个被回收的凭据,结合ReferenceQueue可以让程序在第一时间得到referent被回收的事件,从而做一些额外的clean操作。(如果对ReferenceQueue作用和回调感兴趣,可以先看最下面的 ReferenceQueue 简介)

 

 

SR的作用一般是用作不限大小的 cache(无需remove)。

比如将其 Soft Reference 无限地放入 hashmap 中,而不关心hashmap内的对象数量是否会撑爆heap,也不需要手动 remove。

当Heap容量达到OOM触发条件时,VM会自动回收该map里的所有SoftReferences.

 

Phanton Reference, 是一种特殊的Reference,正如他的名字所表达的,幻影引用,他可以像幻影一样附着在referent上。

当GC在遍历引用关系时,如果发现被phantom reference包装过的referent不存在strong, weak, soft引用时(就是除phantom外没有任何引用,幻影的由来),GC会将 phantom reference 放入 Reference queue。以便程序在另一边通过queue的remove/poll方法,感知referent被GC回收的事件。(如果对 ReferenceQueue作用和回调感兴趣,可以先看最下面 ReferenceQueue 简介)

 

另外,我们知道,GC在回收对象前会先调用对象自身的finalize()方法,如果它有实现的话,然后再清掉内存。而Phantom Reference的回调(enqueue)是在对象的finalize后,回收前触发。这跟 WeakReference不一样。WR是在回收后才通知的。在这个特殊的阶段可以做一些特殊的clean操作。

 

为什么 Phantom Reference 的get总是返回null?

因为phantom reference想做到幻影(除自身外,不跟其他任何引用有关联),所以不允许程序能通过自身的get方法得到referent,而破坏幻影的初衷。

 

实例代码

package com.kenwublog.reference;

 

import java.lang.ref.PhantomReference;

import java.lang.ref.Reference;

import java.lang.ref.ReferenceQueue;

import java.util.HashMap;

 

public class PhantomReferenceTest {

 

    public static void main(String[] args) {

        ReferenceQueue referenceQueue = new ReferenceQueue();

        Object object = new Object() {

            public String toString() {

                return "Referenced Object";

            }

        };

 

        Object data = new Object() {

            public String toString() {

                return "Data";

            }

        };

 

        HashMap map = new HashMap();

        Reference reference = null;

        System.out.println("Testing PhantomReference.");

        reference = new PhantomReference(object, referenceQueue);

 

        map.put(reference, data);

 

        System.out.println(reference.get()); // null

        System.out.println(map.get(reference)); // Data

        System.out.println(reference.isEnqueued()); // false

 

        System.gc();

        System.out.println(reference.get()); // null

        System.out.println(map.get(reference)); // Data

        System.out.println(reference.isEnqueued()); // false

 

        object = null;

        data = null;

 

        System.gc();

        System.out.println(reference.get()); // null

        System.out.println(map.get(reference)); // Data

        System.out.println(reference.isEnqueued()); // true, because object has been reclaimed.

    }

 

}

 

ReferenceQueue,一种当 weak, soft, phantom的referent被GC回收后,提供事件回调的接口。需要在实例化三大reference时,通过构造函数传入,phantom reference是强制需要传入的,weak和soft可不传。

 

回调过程:

 

GC回收referent后(phantom是在回收前,finalize后),将reference enqueue到RQ中,程序通过调用RQ的remove方法来感知reference被GC回收的事件。

remove方法是阻塞的,当没有referent被回收时(GC未调用enqueue),remove方法会一直挂起线程,当有referent被回收时,该方法返回 referent对应的reference对象。

同样,RQ也提供了一个非阻塞的方法 poll,但这样就做不到实时回调了。

 

实例

package com.kenwublog.reference;

 

import java.lang.ref.Reference;

import java.lang.ref.ReferenceQueue;

import java.lang.ref.WeakReference;

import java.util.HashMap;

 

public class ReferenceQueueTest {

 

    public static void main(String[] args) {

        final ReferenceQueue q = new ReferenceQueue();

        String str = new String("AK47");

        WeakReference wr = new WeakReference(str, q);

 

        Thread t = new Thread(){

            @Override

            public void run() {

                try {

                    Reference reference = q.remove();

                    System.out.println(reference + " event fired.");

                } catch (InterruptedException e) {

                    e.printStackTrace();

                }

            }

        };

        t.setDaemon(true);

        t.start();

        System.out.println("Reference Queue is listening.");

 

        str = null; // clear strong reference

        System.out.println("Ready to gc");

        System.gc();

        try {

            Thread.sleep(2000);

        } catch (InterruptedException e) {

            e.printStackTrace();

        }

        System.out.println("wr.get: " + wr.get());

    }

 

}

分享到:
评论

相关推荐

    Java中的引用类型详解:强引用、软引用、弱引用与虚引用

    从JDK 1.2版本开始,Java引入了四种不同级别的引用:强引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Reference)和虚引用(Phantom Reference)。这些引用类型提供了灵活的内存管理策略,允许...

    Java中弱引用软引用虚引用及强引用的区别Java开发Ja

    强引用、弱引用、软引用和虚引用是四种不同的引用强度,它们在垃圾回收机制中扮演着不同的角色。了解这些引用类型对于优化内存使用、防止内存泄漏以及合理地控制对象生命周期至关重要。 1. **强引用(Strong ...

    Java中的强软弱虚引用

    为了更好地理解和控制对象的生命周期,Java提供了四种不同类型的引用:强引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Reference)以及虚引用(Phantom Reference)。每种引用都有其特定的...

    Java 7之基础 - 强引用、弱引用、软引用、虚引用1

    然而,为了更好地控制内存,Java提供了不同类型的引用:强引用、弱引用、软引用和虚引用。这些引用类型允许程序员在特定场景下干预垃圾收集过程,以达到更精细的内存管理。 1. **强引用(Strong Reference)** - *...

    强引用、软引用、弱引用、虚引用1

    从Java SE2开始,Java引入了四种不同类型的引用:强引用、软引用、弱引用和虚引用,它们各自具有不同的特点和用途,有助于程序员更精细地控制对象的生命周期,并优化垃圾回收过程。 1. 强引用(Strong Reference) ...

    Java对象的强、软、弱和虚引用1

    Java对象的引用类型是Java内存管理中的重要概念,特别是在JDK 1.2及后续版本中引入了四种级别的引用:强引用、软引用、弱引用和虚引用,以提供更精细的控制对象生命周期的能力。 1. **强引用(StrongReference)**: ...

    Java中的软引用弱引用和虚引用.docx

    本文将深入探讨Java中三种特殊的引用类型——软引用(Soft Reference)、弱引用(Weak Reference)以及虚引用(Phantom Reference),并分析它们如何帮助我们更好地管理内存资源。 #### 二、基础知识回顾 在深入了解这三...

    Java功底之Reference

    `Reference`类及其子类主要用于处理对象的软引用、弱引用和虚引用,这些引用类型在内存管理,特别是垃圾收集(Garbage Collection,GC)中扮演着关键角色。本文将深入探讨`Reference`类及其相关知识点。 首先,我们...

    java 常见的四种引用

    在Java中,为了更好地管理对象的生命周期,从JDK 1.2开始引入了四种不同级别的引用类型:强引用、软引用、弱引用和虚引用。每种引用类型都有其特定的应用场景,通过灵活运用这些引用类型,开发者可以在内存管理和...

    referenceInJava:Java强引用,软引用,弱引用以及虚引用测试项目

    这个"referenceInJava"项目专注于探讨四种不同类型的引用:强引用、软引用、弱引用和虚引用。这些引用类型与垃圾收集(Garbage Collection, GC)机制密切相关,对于优化内存使用和防止内存泄漏至关重要。 1. **强...

    Java中弱引用和软引用的区别以及虚引用和强引用介绍

    强引用、弱引用、软引用和虚引用这四种引用类型提供了不同的对象生命周期管理策略。下面将详细介绍这些引用的区别及其应用场景。 1. **强引用(Strong Reference)** - 强引用是最常见的引用类型,如普通变量引用。...

    详解JAVA 虚引用

    如果一个对象没有强引用和软引用,对于垃圾回收器而言便是可以被清除的,在清除之前,会调用其finalize方法,如果一个对象已经被调用过finalize方法但是还没有被释放,它就变成了一个虚可达对象。 与软引用和弱引用...

    Android中的软引用和弱引用

    由于弱引用不会阻止垃圾收集,所以使用弱引用的对象在被创建后会很快变得不可达,除非有其他强引用指向它。这在一定程度上保证了内存的有效利用,避免了不必要的内存占用。 在Android中,软引用和弱引用常用于图片...

    Java引用总结--StrongReference、SoftReference、WeakReference、PhantomRef

    Java从1.2版本开始引入了四种引用,分别是强引用(StrongReference)、软引用(SoftReference)、弱引用(WeakReference)和虚引用(PhantomReference)。这四种引用的级别由高到低依次为:强引用 &gt; 软引用 &gt; 弱引用...

    强应用软引用弱引用与垃圾收集的关系1

    本文将深入探讨强引用、软引用、弱引用以及幻象引用这四种引用类型,以及它们与垃圾收集的关系。 1. **强引用(Strong Reference)**: - 强引用是Java中最常见的引用类型,它代表了一个对象的直接访问路径。只要...

    强,软,弱,虚1

    本文将深入探讨四种引用类型:强引用、软引用、弱引用和虚引用。 首先,我们来理解强引用(Strong Reference)。强引用是最常见的引用类型,它代表了程序中的普通对象引用。当一个对象被强引用指向时,该对象被认为...

    Java的四种引用

    从JDK 1.2版本开始,Java引入了一种更为精细的引用类型管理机制,通过四种不同的引用类型:强引用、软引用、弱引用和虚引用,让开发者能够更加灵活地控制对象的生命周期。这种机制不仅提升了Java应用程序对内存使用...

    拓胜技术专家教你如何深入理解Java四种引用类型

    Java中的四种引用类型是Java内存管理的重要组成部分,它们分别是强引用(StrongReference)、软引用(SoftReference)、弱引用(WeakReference)和虚引用(PhantomReference)。每种引用类型具有不同的特点和用途,...

    Java引用类型1

    Java提供了四种不同级别的引用类型:强引用、软引用、弱引用和虚引用(幻象引用),每种引用类型在内存管理中有不同的作用。 1. **强引用(Strong Reference)** - 强引用是最常见的引用类型,即通常的变量赋值。...

    java引用的demo

    本示例“java引用的demo”将深入探讨四种不同类型的引用:强引用、软引用、弱引用和虚引用。这些引用类型对于理解和优化内存管理至关重要,特别是在Android开发中,因为良好的内存管理能够提升应用性能并防止内存...

Global site tag (gtag.js) - Google Analytics