文档章节

java基础之java.lang.ref.Reference

klink
 klink
发布于 2014/06/05 14:39
字数 1235
阅读 158
收藏 0
点赞 0
评论 0

Reference

java.lang.ref类库主要作用在于当内存不足时,能够提醒gc,将一些使用ref定义的变量释放掉以缓解内存不足的压力。java.lang.ref.Reference有三种不同的子类,SoftReference,WeakReference以及PhantomReference。它们分成了三种不同的级别,gc会在不同的情况下一一释放它们引用对象的空间。

SoftReference

当我们希望对象的引用仍驻留在内存里面,直到内存出现不足时,gc会释放由SoftReference引用对象所占的内存空间。所以SoftReference可以用作Cache的实现。

 package io.github.klink;

// containers/References.java
// Demonstrates Reference objects
import java.lang.ref.*;
import java.util.*;

class VeryBig {
	private static final int SIZE = 10000;
	private long[] la = new long[SIZE];
	private String ident;
	public VeryBig(String id) { ident = id; }
	public String toString() { return ident; }
	protected void finalize() {
		System.out.println("Finalizing " + ident);
	}
}

public class References {
	private static ReferenceQueue<VeryBig> rq =
		new ReferenceQueue<VeryBig>();

	public static void checkQueue() {
		Reference<? extends VeryBig> inq = rq.poll();
		if(inq != null)
			System.out.println("In queue: " + inq.get());
	}

	public static void main(String[] args) {
		int size = 10;

		LinkedList<SoftReference<VeryBig>> sa =
			new LinkedList<SoftReference<VeryBig>>();

		for(int i = 0; i < size; i++) {
			sa.add(new SoftReference<VeryBig>(
					new VeryBig("Soft " + i), rq));
			System.out.println("Just created: " + sa.getLast());
			checkQueue();
		}

	System.gc();
	
	
	try {
		Thread.sleep(5000);
	} catch (InterruptedException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	
	for(int i = 0; i < size; i++) {
		checkQueue();
	}

输出为:

Just created: java.lang.ref.SoftReference@5e1077
Just created: java.lang.ref.SoftReference@18b3364
Just created: java.lang.ref.SoftReference@1db05b2
Just created: java.lang.ref.SoftReference@530cf2
Just created: java.lang.ref.SoftReference@76fba0
Just created: java.lang.ref.SoftReference@181ed9e
Just created: java.lang.ref.SoftReference@1175422
Just created: java.lang.ref.SoftReference@949f69
Just created: java.lang.ref.SoftReference@16dadf9
Just created: java.lang.ref.SoftReference@1b8d6f7

WeakReference

WeakReference并不会影响其引用对象的生命周期。换句话说,如果该对象只被WeakReference引用的话,它仍然会被gc回收。但是在gc回收之前,WeakReference会普通的引用没有区别,都可以访问引用对象的成员。WeakReference可用于:一个对象可能会有若干的引用,当我们不清楚这些引用是否仍在的时候,可以通过WeakReference引用该对象,如果该对象仍在内存中的话,WeakReference就可以获取对象的值,如果不在的话,WeakReference将会为Null。

	LinkedList<WeakReference<VeryBig>> wa =
			new LinkedList<WeakReference<VeryBig>>();
	for(int i = 0; i < size; i++) {
		wa.add(new WeakReference<VeryBig>(
			new VeryBig("Weak " + i), rq));
		System.out.println("Just created: " + wa.getLast());
		checkQueue();
	}

	System.gc();
	
	
	try {
		Thread.sleep(5000);
	} catch (InterruptedException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	
	for(int i = 0; i < size; i++) {
		checkQueue();
	}

输出结果为:

Just created: java.lang.ref.WeakReference@18b3364
Just created: java.lang.ref.WeakReference@1db05b2
Just created: java.lang.ref.WeakReference@530cf2
Just created: java.lang.ref.WeakReference@76fba0
Just created: java.lang.ref.WeakReference@181ed9e
Just created: java.lang.ref.WeakReference@1175422
Just created: java.lang.ref.WeakReference@949f69
Just created: java.lang.ref.WeakReference@16dadf9
Just created: java.lang.ref.WeakReference@1b8d6f7
Just created: java.lang.ref.WeakReference@290fbc
Finalizing Weak 9
Finalizing Weak 8
Finalizing Weak 7
Finalizing Weak 6
Finalizing Weak 5
Finalizing Weak 4
Finalizing Weak 3
Finalizing Weak 2
Finalizing Weak 1
Finalizing Weak 0
In queue: null
In queue: null
In queue: null
In queue: null
In queue: null
In queue: null
In queue: null
In queue: null
In queue: null
In queue: null

PhantomReference

PhantomReference与WeakReference一样,不会影响其引用对象的生命周期。PhantomReference与前两个Reference不同的是,它并不会引用对象,(这就是为什么使用PhantomReference的get()方法总是返回null的原因)。我们从它的构造函数可以看到,它有两个参数其中一个是ReferenceQueue,在gc回收时,会将PhantomReference引用的对象插入到ReferenceQueue中。

但是在实际的代码执行过程中,并没有插入到ReferenceQueue,这点让我比较困惑。

	LinkedList<PhantomReference<VeryBig>> pa =
		new LinkedList<PhantomReference<VeryBig>>();
	for(int i = 0; i < size; i++) {
		pa.add(new PhantomReference<VeryBig>(
			new VeryBig("Phantom " + i), rq));
	System.out.println("Just created: " + pa.getLast());
	checkQueue();
	}
	
	System.gc();
	
	try {
		Thread.sleep(1000);
	} catch (InterruptedException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	for(int i = 0; i < size; i++) {
		checkQueue();
	}

输出结果为:

Just created: java.lang.ref.PhantomReference@5e1077
Just created: java.lang.ref.PhantomReference@18b3364
Just created: java.lang.ref.PhantomReference@1db05b2
Just created: java.lang.ref.PhantomReference@530cf2
Just created: java.lang.ref.PhantomReference@76fba0
Just created: java.lang.ref.PhantomReference@181ed9e
Just created: java.lang.ref.PhantomReference@1175422
Just created: java.lang.ref.PhantomReference@949f69
Just created: java.lang.ref.PhantomReference@16dadf9
Just created: java.lang.ref.PhantomReference@1b8d6f7
Finalizing Phantom 9
Finalizing Phantom 8
Finalizing Phantom 7
Finalizing Phantom 6
Finalizing Phantom 5
Finalizing Phantom 4
Finalizing Phantom 3
Finalizing Phantom 2
Finalizing Phantom 1
Finalizing Phantom 0

ReferenceQueue

每一个Reference的实现都会有一个构造函数需要ReferenceQueue作为参数。当Reference的子类绑定一个ReferenceQueue时,Reference所指向的对象一旦被gc回收,gc会再回收之前将对象插入到ReferenceQueue中。

WeakHashMap

WeakHashMap是基于WeakReference实现的一个Map。其特点是,WeakHashMap中的Key如果没有被任何对象引用的话,那么当gc回收垃圾的时候,这些未被引用的Key对应的记录会被删除。

package io.github.klink;

import java.util.*;

class Element {
	private String ident;
	public Element(String id) { ident = id; }
	public String toString() { return ident; }
	public int hashCode() { return ident.hashCode(); }

	public boolean equals(Object r) {
		return r instanceof Element &&
				ident.equals(((Element)r).ident);
	}

	protected void finalize() {
		System.out.println("Finalizing " +
				getClass().getSimpleName() + " " + ident);
	}
}

class Key extends Element {
	public Key(String id) { super(id); }
}

class Value extends Element {
	public Value(String id) { super(id); }
}

public class CanonicalMapping {
	public static void main(String[] args) {
		int size = 1000;
		// Or, choose size via the command line:

		Key[] keys = new Key[size];
		WeakHashMap<Key,Value> map =
				new WeakHashMap<Key,Value>();

		for(int i = 0; i < size; i++) {
			Key k = new Key(Integer.toString(i));
			Value v = new Value(Integer.toString(i));
			if(i % 3 == 0)
				keys[i] = k; // Save as "real" references
			map.put(k, v);
		}
		System.gc();
	}
} 

输出结果为:

Finalizing Key 98
Finalizing Key 625
Finalizing Key 683
Finalizing Key 733
Finalizing Key 779
Finalizing Key 811
Finalizing Key 856
Finalizing Key 901
Finalizing Key 944
Finalizing Key 977
Finalizing Key 998
Finalizing Key 997
Finalizing Key 995
Finalizing Key 994
Finalizing Key 992
Finalizing Key 991
Finalizing Key 989
Finalizing Key 988
Finalizing Key 986
Finalizing Key 985
Finalizing Key 983
Finalizing Key 982
Finalizing Key 980
Finalizing Key 979
Finalizing Key 976
Finalizing Key 974
Finalizing Key 973
Finalizing Key 971
Finalizing Key 970
Finalizing Key 968

© 著作权归作者所有

共有 人打赏支持
klink
粉丝 0
博文 11
码字总数 29450
作品 0
苏州
你所需要的java提升篇大总结

java基础篇深入解析大总结 java基础(一) 深入解析基本类型 java基础(二) 自增自减与贪心规则 java基础(三) 加强型for循环与Iterator java基础(四) java运算顺序的深入解析 java基础(五) Str...

sihailoveyan ⋅ 04/25 ⋅ 0

Java程序员必读书单,家族又添新成员

点击关注异步图书,置顶公众号 每天与你分享IT好书 技术干货 职场知识 参与文末话题讨论,每日赠送异步图书。 ——异步小编 有些革命出其不意地吸引了全世界的眼球。Twitter、Linux操作系统和...

异步社区 ⋅ 05/09 ⋅ 0

Java学习---Java简单认识

前言 小编在学习Java方面的基础知识,发现里面有很多是结合之前的语言的特点发展过来的,不同的地方是,Java有它自己的发展和特点。下面小编先简单地做一下总结,结合看过的1-2章的J2SE视频,...

m18633778874 ⋅ 04/01 ⋅ 0

学编程,学java还是大数据、android?平均月薪23k以上告诉你方向

学编程,学java还是大数据、android?有不少同学在纠结中,最近有不少初学者来问到,学习大数据,学习spark,公司主要使用那些语言编写,每听到这一个问题,起码还是很不错的,证明你已经开始...

编程南风 ⋅ 05/30 ⋅ 0

《成神之路-基础篇》JVM——JVM参数及调优(已完结)

Java内存模型,Java内存管理,Java堆和栈,垃圾回收 本文是[《成神之路系列文章》][1]的第一篇,主要是关于JVM的一些介绍。 持续更新中 JVM参数及调优 JVM实用参数系列 成为Java GC专家(5)...

⋅ 05/05 ⋅ 0

学习大数据需要Java基础吗?

近几年,很多人都听到过一个名词“大数据”也有一部分人选择学习了解大数据,那么大数据到底是什么,学习大数据需要有Java基础吗? 推荐一个大数据学习交流群 119599574每天晚上20:10都有一节...

大数据大咖 ⋅ 06/10 ⋅ 0

安卓开发必备知识体系:Java篇

大家好我是张拭心,自从各位朋友帮点广X开始,我发现我每天更有奔头了,走起路来也更有劲了,说啥也得更新的勤快一点。不过放心,我一定推送有价值的内容给大家,还请朋友们照旧动动手指点点...

d29h1jqy3akvx ⋅ 05/10 ⋅ 0

《成神之路-基础篇》JVM——JVM内存结构(已完结)

Java内存模型,Java内存管理,Java堆和栈,垃圾回收 本文是《成神之路系列文章》的第一篇,主要是关于JVM的一些介绍。 持续更新中 参考文章: Java虚拟机的内存组成以及堆内存介绍 Java堆和栈...

⋅ 05/05 ⋅ 0

Java编程基础知识点和技术点归纳

Java是一种可以撰写跨平台应用软件的面向对象的程序设计语言。Java 技术具有卓越的通用性、高效性、平台移植性和安全性,广泛应用于PC、数据中心、游戏控制台、科学超级计算机、移动电话和互...

Java小辰 ⋅ 05/23 ⋅ 0

方向选择(嵌入式 大数据 java)

嵌入式:单片机之类的 比如指纹解锁底层就是此技术,反正就是和硬件打交道。 大数据:最近很火的概念技术 有点玄玄乎乎的,前途不好定义,不过门槛也是高的,对算法之类的要求还是比较高的 ...

codingcoge ⋅ 05/03 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

js模拟栈和队列

栈和队列 栈:LIFO(先进后出)一种数据结构 队列:LILO(先进先出)一种数据结构 使用的js方法 1.push();可以接收任意数量的参数,把它们逐个推进队尾(数组末尾),并返回修改后的数组长度。 2....

LIAOJIN1 ⋅ 26分钟前 ⋅ 0

180619-Yaml文件语法及读写小结

Yaml文件小结 Yaml文件有自己独立的语法,常用作配置文件使用,相比较于xml和json而言,减少很多不必要的标签或者括号,阅读也更加清晰简单;本篇主要介绍下YAML文件的基本语法,以及如何在J...

小灰灰Blog ⋅ 34分钟前 ⋅ 0

IEC60870-5-104规约传送原因

1:周期循环2:背景扫描3:自发4:初始化5:请求6:激活7:激活确认8:停止激活9:停止激活确认10:激活结束11:远程命令引起的返送信息12:当地命令引起的返送信息13:文件传送20:响应总召...

始终初心 ⋅ 47分钟前 ⋅ 0

【图文经典版】冒泡排序

1、可视化排序过程 对{ 6, 5, 3, 1, 8, 7, 2, 4 }进行冒泡排序的可视化动态过程如下 2、代码实现    public void contextLoads() {// 冒泡排序int[] a = { 6, 5, 3, 1, 8, 7, 2, ...

pocher ⋅ 58分钟前 ⋅ 0

ORA-12537 TNS-12560 TNS-00530 ora-609解决

oracle 11g不能连接,卡住,ORA-12537 TNS-12560 TNS-00530 TNS-12502 tns-12505 ora-609 Windows Error: 54: Unknown error 解决方案。 今天折腾了一下午,为了查这个问题。。找了N多方案,...

lanybass ⋅ 今天 ⋅ 0

IDEA反向映射Mybatis

1.首先在pom文件的plugins中添加maven对mybatis-generator插件的支持 ` <!-- mybatis逆向工程 --><plugin><groupId>org.mybatis.generator</groupId><artifactId>mybatis-generator-ma......

lichengyou20 ⋅ 今天 ⋅ 0

4.10/4.11/4.12 lvm讲解 4.13 磁盘故障小案例

准备磁盘分区 fdisk /dev/sdb n 创建三个新分区,分别1G t 改变分区类型为8e 准备物理卷 pvcreate /dev/sdb1 pvcreate /dev/sdb2 pvcreate /dev/sdb3 pvdisplay/pvs 列出当前的物理卷 pvremo...

Linux_老吴 ⋅ 今天 ⋅ 0

zabbix 3.4安装

#已装好lamp环境 1.安装相关yum仓库 rpm -i http://repo.zabbix.com/zabbix/3.4/rhel/7/x86_64/zabbix-release-3.4-2.el7.noarch.rpm #tip:rpm -ql zabbix-release 看上面这个软件装了哪些东......

山月关 ⋅ 今天 ⋅ 0

Java的Excel导出工具类

首先在POM中引入需要的Jar <dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.47</version></dependency><dependency><groupId>o......

Kxvz ⋅ 今天 ⋅ 0

springboot 使用jsp

目录结构: 启动文件的Application必须在contorller文件的父级 文件路径在src/main/webapp下面 我的配置:前缀是/WEB-INF/jsp/ pom.xml需要加入tomcat-embed-jasper, 对jsp的支持的依赖 <de...

夜醒者 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部