一,定义

在Java中,引用的定义是:如果reference类型的数据中存储的数值代表的是另一块内存的起始地址,就称这块内存代表着一个引用。后面在JDK1.2开始,引用的概念被扩充,引用被分为强引用(StrongReference)、软引用(SoftReference)弱引用、(WeakReference)、虚引用(PhantomReference)。这四种引用的强度关系:强引用>软引用>弱引用>虚引用。

1,强引用:这种引用就是我们在代码中最常用的,类似于“Object o = new Object()”,这个“o”引用就是强引用,只要强引用还存在,GC永远不会回收掉被引用的对象。 
2,软引用:软引用是用来描述那些有用但非必须的对象,在系统发生内存溢出之前会对这些对象进行回收,也就是说内存不足就会回收这些对象,如果内存足够,即使手动GC也不会回收被软件引用指向的对象。 
3,弱引用:弱引用用来描述非必须对象,强度比软引用更弱,当GC工作时,不管当前内存是否足够,都会回收只被弱引用指向的对象。 
4,虚引用:与其他几种引用不同,虚引用不会影响对象的生存时间,也不能通过虚引用来获得一个对象的实例,它唯一的目的就是对象被回收时能收到一个通知。

二,实例说明

说了几种引用的概念,我们结合一些实例来说明他们各自的特性。

  1. public class MyClass {
  2. public static void main(String[] agrs){
  3. MyClass myClass = new MyClass(20,"Zhang san");
  4. SoftReference<MyClass> softReference = new SoftReference<MyClass>(new MyClass(15,"Li si"));
  5. WeakReference<MyClass> weakReference = new WeakReference<MyClass>(new MyClass(10,"Wang er"));
  6. PhantomReference<MyClass> phantomReference = new PhantomReference<>(new MyClass(5,"Ma zi"), new ReferenceQueue<>());
  7.  
  8. System.out.println("strong reference myClass = " + myClass);
  9. System.out.println("soft reference get: " + softReference.get());
  10. System.out.println("weak reference get: " + weakReference.get());
  11. System.out.println("phantom reference get: " + phantomReference.get());
  12.  
  13. }
  14.  
  15. private int age;
  16. private String name;
  17.  
  18. public MyClass(int age, String name){
  19. this.age = age;
  20. this.name = name;
  21. }
  22.  
  23. @Override
  24. public String toString() {
  25. return "name[" + this.name + "] age[" + this.age + "]";
  26. }
  27.  
  28. @Override
  29. protected void finalize() throws Throwable {
  30. super.finalize();
  31. System.out.println("finalize method executed...." + this);
  32. }
  33. }

我们先看上面的例子,一个测试类,main()方法中定义了四个变量,分别是强引用、软引用、弱引用、虚引用,我们看下运行后的打印信息

  1. strong reference myClass = name[Zhang san] age[20]
  2. soft reference get: name[Li si] age[15]
  3. weak reference get: name[Zhang san] age[20]
  4. phantom reference get: null

从打印信息我们可以得知,虚引用虽然指向了一个对象,但是通过该引用得到的对象是null,这就验证了前面我们说的,不能通过虚引用得到对象的实例。 
接下来,我们做点修改,加上显示调用垃圾回收,主要修改如下:

  1. public static void main(String[] agrs){
  2. MyClass myClass = new MyClass(20,"Zhang san");
  3. SoftReference<MyClass> softReference = new SoftReference<MyClass>(new MyClass(15,"Li si"));
  4. WeakReference<MyClass> weakReference = new WeakReference<MyClass>(new MyClass(10,"Wang er"));
  5. PhantomReference<MyClass> phantomReference = new PhantomReference<>(new MyClass(5,"Ma zi"), new ReferenceQueue<>());
  6.  
  7. System.gc();
  8. System.out.println("strong reference myClass = " + myClass);
  9. System.out.println("soft reference get: " + softReference.get());
  10. System.out.println("weak reference get: " + weakReference.get());
  11. System.out.println("phantom reference get: " + phantomReference.get());
  12.  
  13. }

运行结果如下:

  1. strong reference myClass = name[Zhang san] age[20]
  2. finalize method executed....name[Ma zi] age[5]
  3. finalize method executed....name[Wang er] age[10]
  4. soft reference get: name[Li si] age[15]
  5. weak reference get: null
  6. phantom reference get: null

从结果中我们可以看到,当显示调用垃圾回收时,弱引用和虚引用对象都被回收了,这说明弱引用和虚引用指向的对象在发生GC时一定会被回收。但强引用和软引用指向的对象并没有被回收。我们接着做些修改,修改如下:

  1. public static void main(String[] agrs){
  2. MyClass myClass = new MyClass(20,"Zhang san");
  3. SoftReference<MyClass> softReference = new SoftReference<MyClass>(new MyClass(15,"Li si"));
  4. WeakReference<MyClass> weakReference = new WeakReference<MyClass>(new MyClass(10,"Wang er"));
  5. PhantomReference<MyClass> phantomReference = new PhantomReference<>(new MyClass(5,"Ma zi"), new ReferenceQueue<>());
  6. myClass = null;
  7. System.gc();
  8. System.out.println("strong reference myClass = " + myClass);
  9. System.out.println("soft reference get: " + softReference.get());
  10. System.out.println("weak reference get: " + weakReference.get());
  11. System.out.println("phantom reference get: " + phantomReference.get());
  12.  
  13. }

同样看下运行的结果

  1. strong reference myClass = null
  2. finalize method executed....name[Zhang san] age[20]
  3. finalize method executed....name[Ma zi] age[5]
  4. finalize method executed....name[Wang er] age[10]
  5. soft reference get: name[Li si] age[15]
  6. weak reference get: null
  7. phantom reference get: null

可以看出这个时候,强引用指向的对象被回收了,这是因为我们把myClass引用置空了,也就是说name为张三,age为20的对象没被引用了,当发生GC的时候,该对象就会被回收。

三,总结

强引用指向的对象如果被引用,发生GC时是不会被回收的,除非该对象没有被引用;软引用指向的对象在发生GC时不一定会被回收,该对象会被回收的条件是内存不足;弱引用和虚引用指向的对象在发生GC时一定会被回收,此外通过虚引用得不到引用的对象实例。

Java 引用分类:StrongReference、SoftReference、WeakReference、PhantomReference的更多相关文章

  1. Java之引用类型分析(SoftReference/WeakReference/PhantomReference)

    引言: 即使对于Java的很多老鸟来说,如果忽然问他引用的类型,大概率是一脸茫然,不知所措的-.Java中的引用还分类型,神马情况??? 本文将针对这些类型进行分析,帮助您一文知所有类型. Java的 ...

  2. 4种引用与垃圾回收 :StrongReference, SoftReference, WeakReference , PhantomReference

  3. Java引用总结--StrongReference、SoftReference、WeakReference、PhantomReference

    Java引用总结--StrongReference.SoftReference.WeakReference.PhantomReference 1 Java引用介绍 Java从1.2版本开始引入了4种引 ...

  4. Reference SoftReference WeakReference PhantomReference Cleaner 的研究与实践

    最近在看netty的时候看到直接内存的相关概念,为了更详细的了解一下具体原理,搜到了一篇不错的文章 http://lovestblog.cn/blog/2015/05/12/direct-buffer ...

  5. Java核心技术-高级特性(2)- SoftReference, WeakReference and PhantomReference

    Java.lang.ref 是 Java 类库中比较特殊的一个包,它提供了与 Java 垃圾回收器密切相关的引用类.这些引用类对象可以指向其它对象,但它们不同于一般的引用,因为它们的存在并不防碍 Ja ...

  6. Java 引用 WeakReference

    Reference 是一个抽象类,而 SoftReference,WeakReference,PhantomReference 以及 FinalReference 都是继承它的具体类.接下来我们来分别 ...

  7. 你不知道的Java引用

    什么是引用   引用就是保存着一块地址(门牌号)的对象,就像C语言的指针那样,引用可以传递某个数据的地址,如果我们想拿到某一条数据,就要先找到他的地址,然后告诉计算机我去拿这个地址的数据,最后计算机就 ...

  8. Java引用详解-StrongReference SoftReference WeakReference PhantomReference

    1 Java引用介绍 Java从1.2版本开始引入了4种引用,这4种引用的级别由高到低依次为:    强引用  >  软引用  >  弱引用  >  虚引用 ⑴强引用(StrongR ...

  9. 强引用(StrongReference)、弱引用(WeakReference)、软引用(SoftReference)、虚引用(PhantomReference)

    1.强引用(StrongReference) 强引用是使用最普遍的引用.如果一个对象具有强引用,那垃圾回收器绝不会回收它.如下: Object o=new Object(); // 强引用 当内存空间 ...

随机推荐

  1. Spring 4 异常处理

    异常与HTTP状态码的映射(@ResponseStatus) Spring默认会将自身抛出的异常自动映射到合适的状态码,如下是一些示例: 举个例子,当后端抛出如下异常(TypeMismatchExce ...

  2. SQL server学习

    慕课网sql server学习 数据库第一印象:desktop--web server--database server** 几大数据库:sql server.oracle database.DB2. ...

  3. 自动分割mp3等音频视频文件的脚本

    由于种种关系,我需要对一批mp3文件进行分割(切割).每个音频文件大约1小时,需要切成每10分钟1个文件,文件名要带序号.手工分割工作量太大,不符合我等“懒人”的做法.于是找到了大名的”格式工厂“. ...

  4. Oracle数据字典

    数据字典-简介 Oracle数据字典的名称由前缀和后缀组成,使用下划线"_"连接,其代表的含义如下: ● DBA_:包含数据库实例的所有对象信息. ● V$_:当前实例的动态视图, ...

  5. Python导出Excel为Lua/Json/Xml实例教程(三):终极需求

    相关链接: Python导出Excel为Lua/Json/Xml实例教程(一):初识Python Python导出Excel为Lua/Json/Xml实例教程(二):xlrd初体验 Python导出E ...

  6. 萌新笔记——Cardinality Estimation算法学习(二)(Linear Counting算法、最大似然估计(MLE))

    在上篇,我了解了基数的基本概念,现在进入Linear Counting算法的学习. 理解颇浅,还请大神指点! http://blog.codinglabs.org/articles/algorithm ...

  7. 大数据慎行,数据管理要落实到KPI

    近年来,"大数据"一词被IT和互联网行业广泛提及,但真正落到实处的案例没有多少,大数据量支撑.数据挖掘技术.非结构化数据是阻碍的主要原因.大多数企业的信息化并没有达到到成熟水平,关 ...

  8. 第一个C语言的小项目

    这里先写下主要的业务代码,一些库代码稍后补充上 /** * Feed新闻个性化推送 */ #include "push_service_news.h" /** * 保证单进程运行 ...

  9. [LeetCode] Palindrome Permutation II 回文全排列之二

    Given a string s, return all the palindromic permutations (without duplicates) of it. Return an empt ...

  10. [LeetCode] First Missing Positive 首个缺失的正数

    Given an unsorted integer array, find the first missing positive integer. For example,Given [1,2,0]  ...