原文同时还记录在笔者博客:
http://www.newhottopic.com/2013/04/05/java-reference/
Java语言里的引用类似于C/C++语言里的指针,通过引用可以对堆中的对象进行操作。在Java语言中的引用机制里,有四种引用。
一、强引用
这是最常用最普遍的一种引用。一般而言,大多数情况下默认使用的引用就是强引用。比如当你在函数体中创建了一个对象,该对象被分配在堆中,那么通过对象的引用就可以对该对象进行操作。比如:
StringBuffer str = new StringBuffer("not a hello world");
如果上述语句在函数体内运行,那么str做为局部变量是分配在栈上,但StringBuffer类的实例对象”not a hello world”则是分配在堆上。此时str指向StringBuffer实例所在的堆空间,通过str变量就可以操作该实例了,这时str就是StringBuffer的引用。
当然,如果在上述语句之后代码里还有一个赋值语句,如:
StringBuffer str1 = str;
则str1也会在栈上分配有空间存储,也是StringBuffer实例的引用,此时该实例就有两个引用。如果这时执行“==”操作,判断的是两个引用,指向的实例所在的堆空间的地址是否相同,而不是两个实例是否相同。
上面提到的都是强引用。
一般来说,强引用可以直接访问目标对象。当对象实例还有强引用指向时,就不会被JVM回收。但这样也容易有OutOfMemoryException的隐患。
二、软引用
软引用是除了强引用以外最强的引用类型。其构造使用代码如下:
StringBuffer str = new StringBuffer("not a hello world");
SoftReference<StringBuffer> softRerference = new SoftReference<StringBuffer>(str);
这里的softRerference就是对对象实例的软引用。
软引用的特点在于只有其指向的对象实例不会很快的被JVM回收,其只会在堆内存使用很紧张接近阀值时才会回收掉。只要有足够大的内存空间,软引用是可以在内存里存活的。所以这种特点让其适用于对内存空间敏感的Cache。
三、弱引用
弱引用是比软引用还弱的引用类型,使用的构造代码与软引用类似,把SoftReference改成WeakReference即可。其特点是不管内存空间使用多少,只要JVM进行GC时,发现有弱引用都会对其进行回收。当然,垃圾回收的线程优先级也比较低,如果内存足够,那么弱引用的对象也可以存活很久。
弱引用的特点使其可以适用于可有可无的缓存场景。当内存充足时缓存的对象数据可以加速系统,内存紧张时又会被回收掉。
四、虚引用(又叫幽灵引用)
虚引用、幽灵引用,顾名思义,是虚无缥缈的一种引用,是最弱的一种引用。一个对象有虚引用时,相当于没有引用,其随时都可能会被回收掉,并且其返回值永远都是null。我们看JDK源码时就会看到PhantomReference里的get()方法实现如下:
public T get(){
return null;//任何情况下都是只返回null
}
那么虚引用的存在意义是什么呢?它必须是跟引用队列(ReferenceQueue)一起使用的,用来跟踪垃圾回收的过程。
其构造使用的代码如下:
Object ref = new Object();
PhantomReference<Object> phantomReference = new PhantomReference<Object>(ref, new ReferenceQueue<Object>());
当ref被回收时,GC会让该引用进入到引用队列中,此时判断引用队列里有该对象时,我们即可做一些回收前的业务处理,比如记录日志一类的操作。
其实软引用和弱引用里也有类似用法,即构造时与一个引用队列同用,并且在被回收时GC也会将其放入队列中,那么虚引用与其的区别是什么呢? 我们知道Object 的 finalize方法是在gc执行前被调用的,如果某个对象重载了finalize方法,在其内创建本身的强引用(不管是有意的还是无意的)都将导致这一轮的GC无法回收这个对象。并有可能引起很多次GC,最后会导致JVM内有很多Garbage却OutOfMemory,使用PhantomReference就可以避免这个问题,因为PhantomReference是在finalize方法执行后回收的,也就意味着此时已经不可能拿到原来的引用,也就不会出现上述问题。
一般的应用编程不会涉及到Reference编程,但是了解这些知识会对理解GC的工作原理以及性能调优有帮助,在实现一些基础性设施比如缓存时也可能会用到。
分享到:
相关推荐
, 基于最新Java SE 8,完整且准确地阐述Java编程语言及其规范,是深度了解Java语言及其技术细节的权威参考书。, 本书由Java技术的发明者编写,是Java编程语言的权威性技术指南。如果你想知道Java语言构造的精确含义...
目录第1章 Java语言基础知识 1.1 Java语言与面向对象的程序设计 1.1.1 面向对象的程序设计思想 1.1.2 Java语言的特点 1.1.3 Java类库 1.2 Java程序概述 1.2.1 Java开发环境 1.2.2 Application举例 1.2.3 ...
通过对典型程序的研究与分析可以看出JAVA语言的参数传递总是传值调用的,但是对于基本类型的参数和对象类型的参数来说,参数传递的情况不完全相同.Java语言不能直接使用传引用调用,但是可以通过数组的方式模拟传引用...
太阳微系统对Java语言的解释是:“Java编程语言是个简单、面向对象、分布式、解释性、健壮、安全与系统无关、可移植、高性能、多线程和动态的语言” Java不同于一般的编译语言或解释型语言。它首先将源代码编译成...
JAVA 的五种引用类型及引用队列 在介绍 JAVA 的五种引用之前,先介绍一下什么是引用,以及引用和对象之间的关系 什么是引用 众所周知,JAVA 是一种面向对象的语言,在 JAVA 程序运行时,对象是存储在堆内存...
java.applet:包含一些用于创建Java小应用程序的类。...java.lang:包含一些Java语言的基本类与核心类,如String、Math、Integer、System和Runtime,提供常用的功能,这个包中的所有类是被隐式导入的。
Java是一种静态类型的、类基础的、并发性的、面向对象的编程语言。以下是一些Java的主要特性: 平台独立性:这是Java最著名的特性。Java采用"一次编写,到处运行"的方法。Java程序在任何支持Java的平台上都可以运行...
但Java语言很复杂,老师和学生们在理解Java语言的结构时,复杂性成为了最大的障碍。 在本书中,斯坦福大学教授、著名的计算机科学教育领导者Eric S.Roberts着重强调了更适合于初学者的友好讲解方式,使用ACM Java...
引用也是一种数据类型,我们可以把它想象为类似 C 语言中指针的东西,它指示了对象在内存中的地址——只不过我们不能够观察到这个地址究竟是什么。 如果我们定义了不止一个引用指向同一个对象,那么这些引用是不...
引用(Reference)类型 52 存储器分配和布局 53 this引用 55 Java编码约定 56 运算符的优先级 58 升级和表达式的类型转换 62 独立实践 70 第五章:数组 71 学习目标 71 数组的描述 72 创建数组 72 多维数组 78 拷贝...
第2章概述Java虚拟机的整体架构,包括class文件格式、数据类型、原始类型、引用类型、运行时数据区、栈帧、浮点算法、异常等,这对理解本书后面的内容有重要帮助;第3章详述如何将Java语言编写的程序转换为Java...
Java语言特性 Java是一种面向对象的编程语言,具有跨平台、安全性高、易于维护等特点,广泛应用于企业级应用开发。 Java数据类型 Java拥有8种基本数据类型,包括整型、浮点型、字符型等,以及引用数据类型如数组和类...
模块2 Java语言基础 《Java程序设计案例教程》教学课件02Java语言基础全文共48页,当前为第1页。 学习目标 01 掌握标识符、关键字、分隔符、变量和常量的含义和使用方法。 02 了解Java注释的格式和代码书写风格。 03...
1.1 Java语言与面向对象的程序设计 1.2 Java程序概述 1.3 基本数据类型与表达式 1.4 数组的概念 1.5 数组的创建和引用 1.6 本章小结
引用类型参数,相对应的实参和形参链接到同一个对象,在方法中改变了形参引用对象时,其实就是改变了实参引用的对象。 例4.2 TwoInt类中有两个int类型的属性,编写方法swap交换该类对象的两个属性的值,并显示交换...
Java是一种面向对象的编程语言,它支持封装、继承和多态等面向对象的基本概念。Java具有静态类型检查机制,需要在编译时指定变量的类型。Java提供了基本数据类型,如int、double、float等,也支持引用数据类型,如类...
Java 语言与平台 ... 规范引用的一组直接和间接类型可以被视为平台 API 的“核心”部分,与 Java 语言本身密不可分。 去做 允许将规范中定义的类型名称列表作为输入提供 屏幕抓取 HTML 规范以定位直接引用的类
Java是一种强类型语言,这意味着在Java中,每个变量都必须先声明其数据类型,然后才能使用。Java的数据类型可以分为两类:基本数据类型和引用数据类型。基本数据类型包括byte、short、int、long、float、double和...