java引用

目录

为什么将引用分为不同的强度

  • 因为我们需要实现这样一种情况,当内存足够的时候,继续保留,内存空间不够的后则可以回收。

强引用

  • 只要强引用还在,被引用的对象不会被回收
People jiajun=new People();

软引用

  • 系统将要发生内存溢出异常之前,会回收软引用的对象,如果回收后还没有足够的内存,抛出内存溢出异常
  • 使用SoftReference类,将要软引用的对象最为参数传入,
  • 传入ReferenceQuue队列的时候,如果引用的对象被回收,这个引用加入到关联的引用队列
SoftReference(T referent)
创建引用给定对象的新的软引用。
SoftReference(T referent, ReferenceQueue<? super T> q)
创建一个引用给定对象的新的软引用,并向给定队列注册该引用

弱引用

  • 弱引用的对象只能存活在下一次垃圾回收之前,回收时,不管内存是否足够,都会将弱引用的对象回收
  • 使用WeakReference类,将要弱引用的对象作为参数传入
  • 传入ReferenceQuue队列的时候,如果引用的对象被回收,这个引用加入到关联的引用队列中
WeakReference(T referent)
创建引用给定对象的新的弱引用。
WeakReference(T referent, ReferenceQueue<? super T> q)
创建引用给定对象的新的弱引用,并向给定队列注册该引用。

虚引用

  • 虚引用和没有任何引用一样,任何时候都可能被回收
  • 为一个对象设置虚引用关联的唯一目的就是能在这个对象被收集器回收时收到一个系统通知。用于跟踪对象的回收状态
  • 使用PhantoReference类,将要虚引用的对象作为参数传入,此时还需要一个ReferenceQueue 对象
  • 对象被回收后,把这个虚引用加入到与之 关联的引用队列中。
PhantomReference(T referent, ReferenceQueue<? super T> q)
创建一个引用给定对象的新的虚引用,并向给定队列注册它。

ReferenceQueue的作用

  • public Reference poll():从队列中取出一个元素,队列为空则返回null
  • public Reference remove():从队列中出对一个元素,若没有则阻塞至有可出队元素
  • Reference对象所引用的对象被GC回收时,该Reference对象将会被加入引用队列中
ReferenceQueue queue = new ReferenceQueue();
SoftReference ref=new SoftReference(object, queue);
object =null;
  • 当object对象被回收的时候,此时通过ref.get()方法get出来的是null,说明这个对象已经被回收,但是,此时这个ref对象还是存在的,但是现在已经没作用了。引用队列poll出来的是引用对象。所以可以有下面的操作来回收ref对象
SoftReference ref = null; 

while ((ref = (EmployeeRef) q.poll()) != null) {
// 清除ref
}

使用场景

分析

       Student s1=new Student();
HashMap<Student, String> map=new HashMap();
map.put(s1,"jiajun");
s1=null;
  • 在这种情况下,我们想要是student对象被回收,虽然s1=null,但是hashmap中还有对student对象的引用,所以并不能被回收
  • 因此jdk为我们提供了一个WeakHashMap,通过弱引用来管理entry
 private static class Entry<K,V> extends WeakReference<Object> implements Map.Entry<K,V>

实验

public class Test {
public static void main(String[] args) {
String s1=new String("1");
String s2=new String("2");
String s3=new String("3");
Map map=new WeakHashMap();
map.put(s1, "one");
map.put(s2, "two");
map.put(s3, "three");
s1=null;
System.gc();
Iterator iter = map.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry en = (Map.Entry)iter.next();
System.out.printf("next : %s - %s\n",en.getKey(),en.getValue());
}
}
}
  • 输出:next : 2 - two next : 3 - three
  • 将WeakHashMap修改为HashMap,可以发现输出结果是有三个,在这里可以发现弱引用的作用了

总结

比较 强引用 软引用 弱引用 虚引用
使用 People p=new People() SoftReference s=new SoftReference(p) WeakReference w=new WeakReference(p) PhantomReference r=new PhantomReference (p,referenceQueue)
回收情况 有强引用的时候不会被回收 当要内存溢出内存异常的时候,回收软引用的对象 下一次回收一定将他回收
适用情况 有用但非必须对象 非必须对象

我觉得分享是一种精神,分享是我的乐趣所在,不是说我觉得我讲得一定是对的,我讲得可能很多是不对的,但是我希望我讲的东西是我人生的体验和思考,是给很多人反思,也许给你一秒钟、半秒钟,哪怕说一句话有点道理,引发自己内心的感触,这就是我最大的价值。(这是我喜欢的一句话,也是我写博客的初衷)

作者:jiajun 出处: http://www.cnblogs.com/-new/

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。如果觉得还有帮助的话,可以点一下右下角的【推荐】,希望能够持续的为大家带来好的技术文章!想跟我一起进步么?那就【关注】我吧。

jvm系列 (四) ---强、软、弱、虚引用的更多相关文章

  1. java中强,软,弱,虚引用 以及WeakHahMap

    java中强,软,弱,虚引用  以及WeakHahMap   一:强软引用: 参考:http://zhangjunhd.blog.51cto.com/113473/53092/进行分析   packa ...

  2. java中的强,软,弱,虚引用

    引用的应用场景 我们都知道垃圾回收器会回收符合回收条件的对象的内存,但并不是所有的程序员都知道回收条件取决于指向该对象的引用类型.这正是Java中弱引用和软引用的主要区别. 如果一个对象只有弱引用指向 ...

  3. jvm系列(四):jvm知识点总结

    原文链接:http://www.cnblogs.com/ityouknow/p/6482464.html jvm 总体梳理 jvm体系总体分四大块: 类的加载机制 jvm内存结构 GC算法 垃圾回收 ...

  4. jvm系列四、jvm知识点总结

    原文链接:http://www.cnblogs.com/ityouknow/p/6482464.html jvm 总体梳理 jvm体系总体分四大块: 类的加载机制 jvm内存结构 GC算法 垃圾回收 ...

  5. Java 强,弱,软,虚 引用

    import java.lang.ref.SoftReference; import java.lang.ref.WeakReference; public class TestGC { /** * ...

  6. jvm系列四类加载与字节码技术

    四.类加载与字节码技术 1.类文件结构 首先获得.class字节码文件 方法: 在文本文档里写入java代码(文件名与类名一致),将文件类型改为.java java终端中,执行javac X:...\ ...

  7. JVM系列(四):java方法的查找过程实现

    经过前面几章的简单介绍,我们已经大致了解了jvm的启动框架和执行流程了.不过,这些都是些无关痛痒的问题,几行文字描述一下即可. 所以,今天我们从另一个角度来讲解jvm的一些东西,以便可以更多一点认知. ...

  8. jvm系列(四):jvm调优-命令大全(jps jstat jmap jhat jstack jinfo)

    文章同步发布于github博客地址,阅读效果更佳,欢迎品尝 运用jvm自带的命令可以方便的在生产监控和打印堆栈的日志信息帮忙我们来定位问题!虽然jvm调优成熟的工具已经有很多:jconsole.大名鼎 ...

  9. jvm系列(四):jvm调优-命令篇

    运用jvm自带的命令可以方便的在生产监控和打印堆栈的日志信息帮忙我们来定位问题!虽然jvm调优成熟的工具已经有很多:jconsole.大名鼎鼎的VisualVM,IBM的Memory Analyzer ...

随机推荐

  1. 【javascript】数组的操作

    一.常用操作 toString():把数组转换成一个字符串  toLocaleString():把数组转换成一个字符串  join():把数组转换成一个用符号连接的字符串  shift():将数组头部 ...

  2. 几种常见排序算法原理&C语言实现

    一.冒泡排序(以下各法均以从小到大排序为例,定义len为数组array的长度) 原理:比较相邻元素的大小,对于每次循环,按排序的规则把最值移向数组的一端,同时循环次数依次减少. C代码实现 写法一: ...

  3. OpenFlow协议1.0及1.3版本分析

    OpenFlow是SDN控制器和交换之间交流的协议,在SDN领域有着十分重要的地位. OpenFlow协议发展到现在已经经过了1.0.1.3.1.4等版本.其中1.0和1.3版本使用的是最为广泛的. ...

  4. C# 接口基础学习

    什么是接口  接口,在表面上是由几个没有主体代码的方法.属性.索引器.事件,或者它们的组合的集合体,有唯一的名称,可以被类或结构或者其他接口所实现(或者也可以说继承).它在形式上可能是如下的样子: i ...

  5. HDU5727 Necklace(二分图匹配)

    Problem Description SJX has 2*N magic gems. N of them have Yin energy inside while others have Yang ...

  6. 表达式求值(二叉树方法/C++语言描述)(一)

    使用二叉树对算数表达式(以下简称为表达式)进行求值,实质上是将表达式转换为二叉树,对其进行后序遍历,得到后缀表达式的同时可以求得表达式的值.转换和求值的过程也需要借助数据结构栈的帮助. 二叉树数据结构 ...

  7. DHCP服务的部署和配置

    DHCP介绍: DHCP(动态主机配置协议)是一个局域网网络协议,使用UDP协议工作,主要用途:给局域网络或网络服务供应商自动分配IP地址, DHCP有3个端口,其中UDP67和UDP68为正常的DH ...

  8. 【转】Hdu--4135 Co-prime

    Problem Description Given a number N, you are asked to count the number of integers between A and B ...

  9. 中国大学MOOC-翁恺-C语言程序设计习题集-解答汇总

    中国大学MOOC-翁恺-C语言程序设计习题集 PAT 习题集 02-0. 整数四则运算(10) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standar ...

  10. Ruby01: Beginner

    中整個早上都忙著作業,看來是假期懶了一下現在現眼報吧哈哈.在上課之前發一下Ruby 的首章,算是倉促的開始吧. puts puts "Once upon a time... there's ...