Java引用类型具体解释
JVM 的垃圾回收器对于不同类型的引用有不同的处理方式。java中对于一个对象来说,仅仅要有引用的存在,它就会一直存在于内存中。假设这种对象越来越多,超出了JVM中的内存总数,JVM就会抛出OutOfMemory错误。尽管垃圾回收的详细执行是由JVM来控制的。可是开发者仍然能够在一定程度上与垃圾回收器进行交互,其目的在于更好的帮助垃圾回收器管理好应用的内存。这种交互方式就是使用JDK1.2 引入的 java.lang.ref包。
强引用(strong reference)
在一般的 Java 程序中,见到最多的就是强引用(strong reference)。如 Date date = newDate(),date 就是一个对象的强引用。对象的强引用能够在程序中到处传递。
非常多情况下,会同一时候有多个引用指向同一个对象。强引用的存在限制了对象在内存中的存活时间。假如对象 A 中包括了一个对象 B 的强引用。那么普通情况下,对象 B 的存活时间就不会短于对象 A。
假设对象 A 没有显式的把对象 B 的引用设为 null 的话,就仅仅有当对象 A 被垃圾回收之后,对象 B 才不再有引用指向它。才可能获得被垃圾回收的机会。
软引用(soft reference)
软引用(soft reference)在强度上弱于强引用,通过类SoftReference来表示。
它的作用是告诉垃圾回收器,程序中的哪些对象是不那么重要,当内存不足的时候是能够被临时回收的。当JVM中的内存不足的时候。垃圾回收器会释放那 些仅仅被软引用所指向的对象。
假设所有释放完这些对象之后,内存还不足,才会抛出OutOfMemory错误。软引用很适合于创建缓存。当系统内存不足的时候,缓存中的内容是能够被释放的。
比方考虑一个图像编辑器的程序。该程序会把图像文件的所有内容都读取到内存中。以方便进行处理。而用户也能够同一时候打开
多个文件。
当同一时候打开的文件过多的时候,就可能造成内存不足。假设使用软引用来指向图像文件内容的话,垃圾回收器就能够在必要的时候回收掉这些内存。
import java.lang.ref.SoftReference;
public class ImageData {
private String path;
private SoftReference<byte[]> dataRef;
public ImageData(String path) {
this.path = path;
dataRef = new SoftReference<byte[]>(new byte[0]);
}
private byte[] readImage() {
return new byte[1024 * 1024]; // 省去了读取文件的操作
}
public byte[] getData() {
byte[] dataArray = dataRef.get();
if (dataArray == null || dataArray.length == 0) {
dataArray = readImage();
dataRef = new SoftReference<byte[]>(dataArray);
}
return dataArray;
}
}
在执行上面程序的时候,能够使用 -Xmx 參数来限制JVM可用的内存。
因为软引用所指向的对象可能被回收掉,在通过 get方法来获取软引用所实际指向的对象的时候,总是要检查该对象是否还存活。
弱引用(weak reference)
弱引用(weak reference)在强度上弱于软引用。通过类 WeakReference来 表示。它的作用是引用一个对象,可是并不阻止该对象被回收。假设使用一个强引用的话,仅仅要该引用存在,那么被引用的对象是不能被回收的。弱引用则没有这个问题。在垃圾回收器执行的时候。假设一个对象的全部引用都是弱引用的话。该对象会被回收。
弱引用的作用在于解决强引用所带来的对象之间在存活时间上的耦合关系。
弱引用最常见的用处是在集合类中,尤其在哈希表中。哈希表的接口同意使用不论什么Java对象作为键来使用。当一个键值对被放入到哈希表中之后,哈希表
对象本身就有了对这些键和值对象的引用。假设这样的引用是强引用的话,那么仅仅要哈希表对象本身还存活。当中所包括的键和值对象是不会被回收的。假设某个存活 时间非常长的哈希表中包括的键值对非常多。终于就有可能消耗掉JVM中所有的内存。
对于这样的情况的解决的方法就是使用弱引用来引用这些对象,这样哈希表中的键和值对象都能被垃圾回收。Java中提供了 WeakHashMap来满足这一常见需求。
虚引用(phantom reference)
在介绍虚引用之前,要先介绍Java提供的 对象终止化机制(finalization)。
在Object类里面有个 finalize方法。其设计的初衷是在一个对象被真正回收之前,能够用来执行一些清理的工作。由于 Java并没有提供类似 C++的析构函数一样的机制,就通过finalize方法来实现。可是问题在于垃圾回收器的执行时间是不固定的,所以这些清理工作的实际执行时间也是不能预知的。虚引用(phantom reference)能够解决问题。在创建虚引用 PhantomReference的时候必需要指定一个引用队列。当一个对象的finalize方法已经被调用了之后。这个对象的虚引用会被增加到队列中。
通过检查该队列里面的内容就知道一个对象是不是已经准备要被回收了。
在有些情况下,程序会须要在一个对象的可达到性发生变化的时候得到通知。比方某个对象的强引用都已经不存在了,仅仅剩下软引用或是弱引用。可是还须要对引用本身做一些的处理。典型的情景是在哈希表中。
引用对象是作为WeakHashMap中的键对象的,当其引用的实际对象被垃圾回收之后,就须要把该键值对从哈希表中删除。有了引用队列(ReferenceQueue),就能够方便的获取到这些弱引用对象,将它们从表中删除。在软引用和弱引用对象被加入到队列之前,其对实际对象的引用会被自己主动清空。
通过引用队列的 poll/remove方法就能够分别以非堵塞和堵塞的方式获取队列中的引用对象。
參考文献:
深入理解JVM
Java深度探索
Java引用类型具体解释的更多相关文章
- 深入理解Java引用类型
深入理解Java引用类型 在Java中类型可分为两大类:值类型与引用类型.值类型就是基本数据类型(如int ,double 等),而引用类型,是指除了基本的变量类型之外的所有类型(如通过 class ...
- java常用英文解释
java常用名词解释: OO: object-oriented ,面向对象 OOP:object-oriented programming,面向对象编程 Author:JCC Object:对象JDK ...
- Java多线程具体解释
Java多线程具体解释 多线程简单介绍 概述 多线程(multithreading).是指从软件或者硬件上实现多个线程并发运行的技术.具有多线程能力的计算机因有硬件支持而可以在同一时间运行多于一个线程 ...
- Java引用类型之软引用(2)
下面接着上一篇介绍第2阶段和第3阶段的处理逻辑. 2.process_phase2() 第2个阶段移除所有的referent还存活的Reference,也就是从refs_list中移除Referenc ...
- Java引用类型之弱引用与幻像引用
这一篇将介绍弱引用和幻像引用. 1.WeakReference WeakReference也就是弱引用,弱引用和软引用类似,它是用来描述"非必须"的对象的,它的强度比软引用要更弱一 ...
- Java引用类型之最终引用
FinalReference类只有一个子类Finalizer,并且Finalizer由关键字final修饰,所以无法继承扩展.类的定义如下: class FinalReference<T> ...
- Java到底是解释型还是编译型语言
Java到底是解释型还是编译型语言? 定义 回答这个问题,我们首先来看下概念: 开发人员编写代码,语言是人类可理解的方式,是具有语义的,然而计算机无法理解和执行,因此需要做一层转换. 解释型语言: 运 ...
- Java keyword具体解释
訪问控制修饰符号 1) private 私有的 private keyword是訪问控制修饰符,能够应用于类.方法或字段(在类中声明的变量). 仅仅能在声明 private(内部)类.方 ...
- JAVA Calendar具体解释
(在文章的最后,将会介绍Date类,假设有兴趣,能够直接翻到最后去阅读) 到底什么是一个 Calendar 呢?中文的翻译就是日历,那我们立马能够想到我们生活中有阳(公)历.阴(农)历之分.它们的差别 ...
随机推荐
- wkhtmltopdf 生成pdf
public class PdfHelper { static string RootPath { get { string AppPath = ""; HttpContext H ...
- USB基础简介
一.USB2.0 Universal Serial Bus (通用串行总线) 符合USB总线数据通信要求的通信协议 1.意义 1.易用(热插拔.即插即用) 2.易扩充(USBHub可同时操作127个 ...
- poj 3263 Tallest Cow
一个压了很久的题目,确实很难想,看了别人的做法后总算明白了. 首先要明白一点,因为题目说明了不会有矛盾,所以题目给出来的区间是不能相交的,否则是矛盾的.(原因自己想) 然后既然区间只能是包含的,就很明 ...
- 2014 I/O归来:Google连接一切
6月,WWDC 2014与Google I/O (大部分演讲视频都公开.Youtube须要FQ,很值得一看)相继召开.今年是我第三年參加Google I/O大会. 三年间.Google积累了非常多技 ...
- Java中二进制、十进制、十六进制及ASCII码与String及字节数组与十六进制之间的转换
public class DigitalTrans { /** * 数字字符串转ASCII码字符串 * * @param String * 字符串 * @return ASCII字符串 */ publ ...
- SQL SERVER 2008- 字符串函数
/* 1,ASCII返回字符表达式中最左侧字符的ASCII代码值 仅返回首字母的ASCII码值 parameter char或varchar returns integer */ SELECT ASC ...
- 前端javascript框架之AngularJS学习笔记
<!doctype html><html lang="en" ng-app><head><meta charset="utf-8 ...
- Kendo UI开发教程(21): Kendo MVVM 数据绑定(十) Source
Source绑定可以把ViewModel的值和由Kendo模板定义的目标元素绑定,如果ViewModel的值发生变化,被绑定的目标元素也随之发生变化.模板由属性data-template指定,它的值为 ...
- greatis很不错,出售源代码
http://www.greatis.com/delphicb/ 特别是: http://www.greatis.com/delphicb/imgedit/
- iText 文本
iText中用文本块(Chunk).短语(Phrase)和段落(paragraph)处理文本. 文本块(Chunk)是处理文本的最小单位,有一串带格式(包括字体.颜色.大小)的字符串组成.如以下代码就 ...