- 浏览: 188087 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
duguyiren3476:
我现在的版本是drill0.8.0版本的,搭建了分布式4个节点 ...
walter的drill笔试之二-安装与部署 -
zhangth:
写的不错,受教了
图片分离之图片服务器问题 -
lt200819:
zh55com 写道如何查询mysql数据?如何查询hbase ...
walter的drill笔试之二-安装与部署 -
zh55com:
如何查询mysql数据?如何查询hbase数据?
walter的drill笔试之二-安装与部署 -
QuarterLifeForJava:
不错,挺好的,那如果是update、delete、insert ...
Mysql百万级数据查询优化
SoftReference、Weak Reference和PhantomRefrence分析和比较
本文将谈一下对SoftReference(软引用)、WeakReference(弱引用)和PhantomRefrence(虚引用)的理解,这三个类是对heap中java对象的应用,通过这个三个类可以和gc做简单的交互。
强引用:
除了上面提到的三个引用之外,还有一个引用,也就是最长用到的那就是强引用.例如:
Java代码
1.Object o=new Object();
2.Object o1=o;
上面代码中第一句是在heap堆中创建新的Object对象通过o引用这个对象,第二句是通过o建立o1到new Object()这个heap堆中的对象的引用,这两个引用都是强引用.只要存在对heap中对象的引用,gc就不会收集该对象.如果通过如下代码:
Java代码
1.o=null;
2.o1=null;
如果显式地设置o和o1为null,或超出范围,则gc认为该对象不存在引用,这时就可以收集它了。可以收集并不等于就一会被收集,什么时候收集这要取决于gc的算法,这要就带来很多不确定性。例如你就想指定一个对象,希望下次gc运行时把它收集了,那就没办法了,有了其他的三种引用就可以做到了。其他三种引用在不妨碍gc收集的情况下,可以做简单的交互。
heap中对象有强可及对象、软可及对象、弱可及对象、虚可及对象和不可到达对象。应用的强弱顺序是强、软、弱、和虚。对于对象是属于哪种可及的对象,由他的最强的引用决定。如下:
Java代码
1.String abc=new String("abc"); //1
2.SoftReference<String> abcSoftRef=new SoftReference<String>(abc); //2
3.WeakReference<String> abcWeakRef = new WeakReference<String>(abc); //3
4.abc=null; //4
5.abcSoftRef.clear();//5
上面的代码中:
第一行在heap对中创建内容为“abc”的对象,并建立abc到该对象的强引用,该对象是强可及的。
第二行和第三行分别建立对heap中对象的软引用和弱引用,此时heap中的对象仍是强可及的。
第四行之后heap中对象不再是强可及的,变成软可及的。同样第五行执行之后变成弱可及的。
SoftReference(软引用)
软引用是主要用于内存敏感的高速缓存。在jvm报告内存不足之前会清除所有的软引用,这样以来gc就有可能收集软可及的对象,可能解决内存吃紧问题,避免内存溢出。什么时候会被收集取决于gc的算法和gc运行时可用内存的大小。当gc决定要收集软引用是执行以下过程,以上面的abcSoftRef为例:
1 首先将abcSoftRef的referent设置为null,不再引用heap中的new String("abc")对象。
2 将heap中的new String("abc")对象设置为可结束的(finalizable)。
3 当heap中的new String("abc")对象的finalize()方法被运行而且该对象占用的内存被释放, abcSoftRef被添加到它的ReferenceQueue中。
注:对ReferenceQueue软引用和弱引用可以有可无,但是虚引用必须有,参见:
Java代码
Reference(T paramT, ReferenceQueue<? super T>paramReferenceQueue)
被 Soft Reference 指到的对象,即使没有任何 Direct Reference,也不会被清除。一直要到 JVM 内存不足且 没有 Direct Reference 时才会清除,SoftReference 是用来设计 object-cache 之用的。如此一来 SoftReference 不但可以把对象 cache 起来,也不会造成内存不足的错误 (OutOfMemoryError)。我觉得 Soft Reference 也适合拿来实作 pooling 的技巧。
A obj = new A();
SoftRefenrence sr = new SoftReference(obj);
引用时
if(sr!=null){
obj = sr.get();
}else{
obj = new A();
sr = new SoftReference(obj);
}
弱引用
当gc碰到弱可及对象,并释放abcWeakRef的引用,收集该对象。但是gc可能需要对此运用才能找到该弱可及对象。通过如下代码可以了明了的看出它的作用:
Java代码
1.String abc=new String("abc");
2.WeakReference<String> abcWeakRef = new WeakReference<String>(abc);
3.abc=null;
4.System.out.println("before gc: "+abcWeakRef.get());
5.System.gc();
6.System.out.println("after gc: "+abcWeakRef.get());
运行结果:
before gc: abc
after gc: null
gc收集弱可及对象的执行过程和软可及一样,只是gc不会根据内存情况来决定是不是收集该对象。
如果你希望能随时取得某对象的信息,但又不想影响此对象的垃圾收集,那么你应该用 Weak Reference 来记住此对象,而不是用一般的 reference。
A obj = new A();
WeakReference wr = new WeakReference(obj);
obj = null;
//等待一段时间,obj对象就会被垃圾回收
...
if (wr.get()==null) {
System.out.println("obj 已经被清除了 ");
} else {
System.out.println("obj 尚未被清除,其信息是 "+obj.toString());
}
...
}
在此例中,透过 get() 可以取得此 Reference 的所指到的对象,如果返回值为 null 的话,代表此对象已经被清除。
这类的技巧,在设计 Optimizer 或 Debugger 这类的程序时常会用到,因为这类程序需要取得某对象的信息,但是不可以 影响此对象的垃圾收集。
PhantomRefrence(虚引用)
虚顾名思义就是没有的意思,建立虚引用之后通过get方法返回结果始终为null,通过源代码你会发现,虚引用通向会把引用的对象写进referent,只是get方法返回结果为null.先看一下和gc交互的过程在说一下他的作用.
1 不把referent设置为null, 直接把heap中的new String("abc")对象设置为可结束的(finalizable).
2 与软引用和弱引用不同, 先把PhantomRefrence对象添加到它的ReferenceQueue中.然后在释放虚可及的对象.
你会发现在收集heap中的new String("abc")对象之前,你就可以做一些其他的事情.通过以下代码可以了解他的作用.
Java代码
1.import java.lang.ref.PhantomReference;
2.import java.lang.ref.Reference;
3.import java.lang.ref.ReferenceQueue;
4.import java.lang.reflect.Field;
5.
6.public class Test {
7. public static boolean isRun = true;
8.
9. public static void main(String[] args) throws Exception {
10. String abc = new String("abc");
11. System.out.println(abc.getClass() + "@" + abc.hashCode());
12. final ReferenceQueue referenceQueue = new ReferenceQueue<String>();
13. new Thread() {
14. public void run() {
15. while (isRun) {
16. Object o = referenceQueue.poll();
17. if (o != null) {
18. try {
19. Field rereferent = Reference.class
20. .getDeclaredField("referent");
21. rereferent.setAccessible(true);
22. Object result = rereferent.get(o);
23. System.out.println("gc will collect:"
24. + result.getClass() + "@"
25. + result.hashCode());
26. } catch (Exception e) {
27.
28. e.printStackTrace();
29. }
30. }
31. }
32. }
33. }.start();
34. PhantomReference<String> abcWeakRef = new PhantomReference<String>(abc,
35. referenceQueue);
36. abc = null;
37. Thread.currentThread().sleep(3000);
38. System.gc();
39. Thread.currentThread().sleep(3000);
40. isRun = false;
41. }
42.
43.}
结果为
class java.lang.String@96354
gc will collect:class java.lang.String@96354
本文将谈一下对SoftReference(软引用)、WeakReference(弱引用)和PhantomRefrence(虚引用)的理解,这三个类是对heap中java对象的应用,通过这个三个类可以和gc做简单的交互。
强引用:
除了上面提到的三个引用之外,还有一个引用,也就是最长用到的那就是强引用.例如:
Java代码
1.Object o=new Object();
2.Object o1=o;
上面代码中第一句是在heap堆中创建新的Object对象通过o引用这个对象,第二句是通过o建立o1到new Object()这个heap堆中的对象的引用,这两个引用都是强引用.只要存在对heap中对象的引用,gc就不会收集该对象.如果通过如下代码:
Java代码
1.o=null;
2.o1=null;
如果显式地设置o和o1为null,或超出范围,则gc认为该对象不存在引用,这时就可以收集它了。可以收集并不等于就一会被收集,什么时候收集这要取决于gc的算法,这要就带来很多不确定性。例如你就想指定一个对象,希望下次gc运行时把它收集了,那就没办法了,有了其他的三种引用就可以做到了。其他三种引用在不妨碍gc收集的情况下,可以做简单的交互。
heap中对象有强可及对象、软可及对象、弱可及对象、虚可及对象和不可到达对象。应用的强弱顺序是强、软、弱、和虚。对于对象是属于哪种可及的对象,由他的最强的引用决定。如下:
Java代码
1.String abc=new String("abc"); //1
2.SoftReference<String> abcSoftRef=new SoftReference<String>(abc); //2
3.WeakReference<String> abcWeakRef = new WeakReference<String>(abc); //3
4.abc=null; //4
5.abcSoftRef.clear();//5
上面的代码中:
第一行在heap对中创建内容为“abc”的对象,并建立abc到该对象的强引用,该对象是强可及的。
第二行和第三行分别建立对heap中对象的软引用和弱引用,此时heap中的对象仍是强可及的。
第四行之后heap中对象不再是强可及的,变成软可及的。同样第五行执行之后变成弱可及的。
SoftReference(软引用)
软引用是主要用于内存敏感的高速缓存。在jvm报告内存不足之前会清除所有的软引用,这样以来gc就有可能收集软可及的对象,可能解决内存吃紧问题,避免内存溢出。什么时候会被收集取决于gc的算法和gc运行时可用内存的大小。当gc决定要收集软引用是执行以下过程,以上面的abcSoftRef为例:
1 首先将abcSoftRef的referent设置为null,不再引用heap中的new String("abc")对象。
2 将heap中的new String("abc")对象设置为可结束的(finalizable)。
3 当heap中的new String("abc")对象的finalize()方法被运行而且该对象占用的内存被释放, abcSoftRef被添加到它的ReferenceQueue中。
注:对ReferenceQueue软引用和弱引用可以有可无,但是虚引用必须有,参见:
Java代码
Reference(T paramT, ReferenceQueue<? super T>paramReferenceQueue)
被 Soft Reference 指到的对象,即使没有任何 Direct Reference,也不会被清除。一直要到 JVM 内存不足且 没有 Direct Reference 时才会清除,SoftReference 是用来设计 object-cache 之用的。如此一来 SoftReference 不但可以把对象 cache 起来,也不会造成内存不足的错误 (OutOfMemoryError)。我觉得 Soft Reference 也适合拿来实作 pooling 的技巧。
A obj = new A();
SoftRefenrence sr = new SoftReference(obj);
引用时
if(sr!=null){
obj = sr.get();
}else{
obj = new A();
sr = new SoftReference(obj);
}
弱引用
当gc碰到弱可及对象,并释放abcWeakRef的引用,收集该对象。但是gc可能需要对此运用才能找到该弱可及对象。通过如下代码可以了明了的看出它的作用:
Java代码
1.String abc=new String("abc");
2.WeakReference<String> abcWeakRef = new WeakReference<String>(abc);
3.abc=null;
4.System.out.println("before gc: "+abcWeakRef.get());
5.System.gc();
6.System.out.println("after gc: "+abcWeakRef.get());
运行结果:
before gc: abc
after gc: null
gc收集弱可及对象的执行过程和软可及一样,只是gc不会根据内存情况来决定是不是收集该对象。
如果你希望能随时取得某对象的信息,但又不想影响此对象的垃圾收集,那么你应该用 Weak Reference 来记住此对象,而不是用一般的 reference。
A obj = new A();
WeakReference wr = new WeakReference(obj);
obj = null;
//等待一段时间,obj对象就会被垃圾回收
...
if (wr.get()==null) {
System.out.println("obj 已经被清除了 ");
} else {
System.out.println("obj 尚未被清除,其信息是 "+obj.toString());
}
...
}
在此例中,透过 get() 可以取得此 Reference 的所指到的对象,如果返回值为 null 的话,代表此对象已经被清除。
这类的技巧,在设计 Optimizer 或 Debugger 这类的程序时常会用到,因为这类程序需要取得某对象的信息,但是不可以 影响此对象的垃圾收集。
PhantomRefrence(虚引用)
虚顾名思义就是没有的意思,建立虚引用之后通过get方法返回结果始终为null,通过源代码你会发现,虚引用通向会把引用的对象写进referent,只是get方法返回结果为null.先看一下和gc交互的过程在说一下他的作用.
1 不把referent设置为null, 直接把heap中的new String("abc")对象设置为可结束的(finalizable).
2 与软引用和弱引用不同, 先把PhantomRefrence对象添加到它的ReferenceQueue中.然后在释放虚可及的对象.
你会发现在收集heap中的new String("abc")对象之前,你就可以做一些其他的事情.通过以下代码可以了解他的作用.
Java代码
1.import java.lang.ref.PhantomReference;
2.import java.lang.ref.Reference;
3.import java.lang.ref.ReferenceQueue;
4.import java.lang.reflect.Field;
5.
6.public class Test {
7. public static boolean isRun = true;
8.
9. public static void main(String[] args) throws Exception {
10. String abc = new String("abc");
11. System.out.println(abc.getClass() + "@" + abc.hashCode());
12. final ReferenceQueue referenceQueue = new ReferenceQueue<String>();
13. new Thread() {
14. public void run() {
15. while (isRun) {
16. Object o = referenceQueue.poll();
17. if (o != null) {
18. try {
19. Field rereferent = Reference.class
20. .getDeclaredField("referent");
21. rereferent.setAccessible(true);
22. Object result = rereferent.get(o);
23. System.out.println("gc will collect:"
24. + result.getClass() + "@"
25. + result.hashCode());
26. } catch (Exception e) {
27.
28. e.printStackTrace();
29. }
30. }
31. }
32. }
33. }.start();
34. PhantomReference<String> abcWeakRef = new PhantomReference<String>(abc,
35. referenceQueue);
36. abc = null;
37. Thread.currentThread().sleep(3000);
38. System.gc();
39. Thread.currentThread().sleep(3000);
40. isRun = false;
41. }
42.
43.}
结果为
class java.lang.String@96354
gc will collect:class java.lang.String@96354
发表评论
-
清除C/C++/JAVA中的注释
2013-09-27 12:49 1394import java.io.FileInputStr ... -
深入JAVA虚拟机
2013-07-24 16:11 788判断对象已经死的方法 ... -
Apache Maven 入门篇(下)-在Eclipse中使用Maven插件
2013-05-06 19:30 1931简介 本文介绍如何在Eclipse中通过maven插件编 ... -
Apache Maven 入门篇 ( 上 )
2013-05-06 19:21 861写这个 maven 的入门篇是因为之前在一个开发者会的动手 ... -
Apache Maven 入门篇(中)
2013-05-06 19:19 955第一篇文章大概的介绍了一下Apache Maven以 ... -
java 动态类型安全
2013-04-12 15:49 1426动态类型安全主要是在泛型容器中遇到的。因为可 ... -
JAVA中的内存泄露
2013-04-12 09:57 779很长时间以前,研究过JAVA的内存泄露,正好今天找到这篇帖 ... -
RPC和RMI的区别
2013-04-07 14:08 901远程对象方法调用并不是新概念,远程过程调用 (RPC-re ... -
Memcached的java客户端
2013-03-28 21:55 751Memcached 客户端程序 Memcached的jav ... -
HashMap和TreeMap
2013-03-26 11:32 7261.AbstractMap抽象类和SortedMap接口 ... -
Lucene 简介
2013-03-19 10:36 596Lucene 简介 Lucene 是一个基于 Java 的 ... -
当前几个主要的Lucene中文分词器的比较
2013-03-19 10:16 8581. 基本介绍: paoding :Lucene中文分词 ... -
java动态代理(JDK和cglib)
2013-01-17 23:48 792JAVA的动态代理 代理模式 代理模式是常用的java设计模 ... -
读取配置文件
2012-10-14 21:30 890必须包: commons-configuration-1.5. ... -
Override错误
2012-10-10 17:27 499一、java @override 报错处理 有时候在自 ... -
Java解析XML文件的四种方法
2012-10-08 10:40 6611.介绍 1)DOM(JAXP ... -
java.lang.OutOfMemoryError: PermGen space及其解决方法
2012-08-24 23:43 683PermGen space的全称是Permanent ... -
Myeclipse调整虚拟内存大小
2012-06-21 16:14 987当程序运行,出行OutOfMemoryError的错误时候,一 ... -
DriverManager和Class.forName()的异同
2012-03-26 09:33 1174在学习JDBC的时候,通常有两种方式去注册数据库驱动程序(这里 ... -
Java 的 PermGen 概念的认识,以及相关问题的处理方法
2011-11-21 12:04 808PermGen space的全称是Permanent Gene ...
相关推荐
基于springboot大学生就业信息管理系统源码数据库文档.zip
基于java的驾校收支管理可视化平台的开题报告
时间序列 原木 间隔5秒钟 20241120
毕业设计&课设_基于 Vue 的电影在线预订与管理系统:后台 Java(SSM)代码,为毕业设计项目.zip
基于springboot课件通中小学教学课件共享平台源码数据库文档.zip
基于java的网上购物商城的开题报告
Delphi人脸检测与识别Demo1fdef-main.zip
基于java的咖啡在线销售系统的开题报告
基于java的自助医疗服务系统的开题报告.docx
内容概要:本文档全面介绍了Visual Basic(VB)编程语言的基础知识和高级应用。首先概述了VB的基本特性和开发环境,随后详细讲述了VB的数据类型、变量、运算符、控制结构、数组、过程与函数、变量作用域等内容。接着介绍了窗体设计、控件使用、菜单与工具栏的设计,文件操作、数据库访问等关键知识点。最后讨论了VB的学习方法、发展历史及其在桌面应用、Web应用、数据库应用、游戏开发和自动化脚本编写等领域的广泛应用前景。 适合人群:初学者和中级程序员,尤其是希望快速掌握Windows桌面应用开发的人群。 使用场景及目标:①掌握VB的基础语法和开发环境;②学会使用VB创建复杂的用户界面和功能完整的应用程序;③理解数据库操作、文件管理和网络编程等高级主题。 其他说明:Visual Basic是一种简单易学且功能强大的编程语言,尤其适合用于开发Windows桌面应用。文中不仅覆盖了基础知识,还包括了大量的实用案例和技术细节,帮助读者快速提升编程技能。
基于java的疫情期间高校防控系统开题报告.docx
基于springboot+vue社区老年人帮扶系统源码数据库文档.zip
基于java的超市商品管理系统的开题报告.docx
基于SpringBoot房屋买卖平台源码数据库文档.zip
xdu限通院23微处理器系统与应用大作业(两只老虎),适应于汇编语言keil软件,
<项目介绍> - 新闻类网站系统,基于SSM(Spring、Spring MVC、MyBatis)+MySQL开发,高分成品毕业设计,附带往届论文 - 不懂运行,下载完可以私聊问,可远程教学 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 --------
基于java的学生网上请假系统的开题报告.docx
社会经济繁荣发展的今天,电子商务得到了飞速发展,网上交易越来越彰显出其独特的优越性,在人们的日常生活中,出现了各种类型的交易网站。其中一个就是车辆易主交易网站,它是一个服务于用户买卖二手车辆的交易网站,为用户提供了平等互利、方便快捷的网上交易平台,通过这一类型的网站,用户可自由出售和购买车辆。 本课题主要根据车辆本身的特性,充分发挥互联网的特点与优势,构建一个以二手车辆为商品、基于互联网平台的车辆易主业务交易管理系统,并根据车辆易主业务交易管理系统的应用需求,进行需求分析,进而对网站系统作规划设计。采用IDEA为运行平台,以SSH为框架,运用HTML语言、JSP技术、MySql数据库、JSP与后台数据库链接等关键技术建设二手车网上交易系统,构建车辆易主交易系统的会员注册与登录,网站首页展示、用户发布商品车辆,用户求购商品车辆,分页浏览、购物系统、用户后台管理、管理员用户后台管理等功能,并使这些功能得以实现并更好为用户服务。网站整体构建完成且测试成功后,用户可以进入网站进行注册、登录,登录后,用户可以在网站上发布自己的闲置车辆或者寻找想要购买的车辆,还可以收藏车辆,管理发布和收藏的车辆,
SQLite3的向量扩展库,windows dll,版本0.1.5
基于C++实现(控制台)商品库存管理系统