Java技术栈

www.javastack.cn

打开网站看更多优质文章

作者:CodeBear的园子

来源:www.cnblogs.com/CodeBear/p/12447554.html

Java中的四种引用

Java中有四种引用类型:强引用、软引用、弱引用、虚引用。

Java为什么要设计这四种引用

Java的内存分配和内存回收,都不需要程序员负责,都是由伟大的JVM去负责,一个对象是否可以被回收,主要看是否有引用指向此对象,说的专业点,叫可达性分析。

Java设计这四种引用的主要目的有两个:

可以让程序员通过代码的方式来决定某个对象的生命周期;

有利用垃圾回收。

强引用

强引用是最普遍的一种引用,我们写的代码,99.9999%都是强引用:

Object o = new Object();

这种就是强引用了,是不是在代码中随处可见,最亲切。

只要某个对象有强引用与之关联,这个对象永远不会被回收,即使内存不足,JVM宁愿抛出OOM,也不会去回收。

那么什么时候才可以被回收呢?当强引用和对象之间的关联被中断了,就可以被回收了。

我们可以手动把关联给中断了,方法也特别简单:

o = null;

我们可以手动调用GC,看看如果强引用和对象之间的关联被中断了,资源会不会被回收,为了更方便、更清楚的观察到回收的情况,我们需要新写一个类,然后重写finalize方法,下面我们来进行这个实验:

public class Student{    @Override

protected void finalize() throws Throwable{

System.out.println("Student 被回收了");

}

}

public static void main(String[] args){

Student student = new Student();

student = null;

System.gc();

}

运行结果:

Student 被回收了

可以很清楚的看到资源被回收了。

当然,在实际开发中,千万不要重写finalize方法

在实际的开发中,看到有一些对象被手动赋值为NULL,很大可能就是为了“特意提醒”JVM这块资源可以进行垃圾回收了。点击这里获取一份 JVM 实战教程。

软引用

下面先来看看如何创建一个软引用:

SoftReferencestudentSoftReference=new SoftReference(new Student());

软引用就是把对象用SoftReference包裹一下,当我们需要从软引用对象获得包裹的对象,只要get一下就可以了:

SoftReferencestudentSoftReference=new SoftReference(new Student());

Student student = studentSoftReference.get();

System.out.println(student);

软引用有什么特点呢:

当内存不足,会触发JVM的GC,如果GC后,内存还是不足,就会把软引用的包裹的对象给干掉,也就是只有在内存不足,JVM才会回收该对象。

还是一样的,必须做实验,才能加深印象:

SoftReference softReference = new SoftReference(new byte[1024*1024*10]);

System.out.println(softReference.get());

System.gc();

System.out.println(softReference.get());

byte[] bytes = new byte[1024 * 1024 * 10];

System.out.println(softReference.get());

我定义了一个软引用对象,里面包裹了byte[],byte[]占用了10M,然后又创建了10Mbyte[]。

运行程序,需要带上一个参数:

-Xmx20M

代表最大堆内存是20M。

运行结果:

[B@11d7fff

[B@11d7fff

null

可以很清楚的看到手动完成GC后,软引用对象包裹的byte[]还活的好好的,但是当我们创建了一个10M的byte[]后,最大堆内存不够了,所以把软引用对象包裹的byte[]给干掉了,如果不干掉,就会抛出OOM。

软引用到底有什么用呢?比较适合用作缓存,当内存足够,可以正常的拿到缓存,当内存不够,就会先干掉缓存,不至于马上抛出OOM。说到缓存,大家可以关注微信公众号Java技术栈获取更多干货。

弱引用

弱引用的使用和软引用类似,只是关键字变成了WeakReference:

WeakReference weakReference = new WeakReference(new byte[1024\*1024\*10]);

System.out.println(weakReference.get());

弱引用的特点是不管内存是否足够,只要发生GC,都会被回收:

WeakReference weakReference = new WeakReference(new byte[1]);

System.out.println(weakReference.get());

System.gc();

System.out.println(weakReference.get());

运行结果:

[B@11d7fffnull

可以很清楚的看到明明内存还很充足,但是触发了GC,资源还是被回收了。

弱引用在很多地方都有用到,比如ThreadLocal、WeakHashMap。

虚引用

虚引用又被称为幻影引用,我们来看看它的使用:

ReferenceQueue queue = new ReferenceQueue();

PhantomReference reference = new PhantomReference(new byte[1], queue);

System.out.println(reference.get());

虚引用的使用和上面说的软引用、弱引用的区别还是挺大的,我们先不管ReferenceQueue 是个什么鬼,直接来运行:

null

竟然打印出了null,我们来看看get方法的源码:

public T get() {

return null;

}

这是几个意思,竟然直接返回了null。

这就是虚引用特点之一了:无法通过虚引用来获取对一个对象的真实引用。

那虚引用存在的意义是什么呢?这就要回到我们上面的代码了,我们把代码复制下,以免大家再次往上翻:

ReferenceQueue queue = new ReferenceQueue();

PhantomReference reference = new PhantomReference(new byte[1], queue);

System.out.println(reference.get());

创建虚引用对象,我们除了把包裹的对象传了进去,还传了一个ReferenceQueue,从名字就可以看出它是一个队列。

虚引用的特点之二就是 虚引用必须与ReferenceQueue一起使用,当GC准备回收一个对象,如果发现它还有虚引用,就会在回收之前,把这个虚引用加入到与之关联的ReferenceQueue中。

我们来用代码实践下吧:

运行结果:

Student 被回收了

虚引用被回收了:java.lang.ref.PhantomReference@1ade6f1

我们简单的分析下代码:

第一个线程往集合里面塞数据,随着数据越来越多,肯定会发生GC。

第二个线程死循环,从queue里面拿数据,如果拿出来的数据不是null,就打印出来。

从运行结果可以看到:当发生GC,虚引用就会被回收,并且会把回收的通知放到ReferenceQueue中。

虚引用有什么用呢?在NIO中,就运用了虚引用管理堆外内存。

最近热文:

扫码关注

Java技术栈

公众号干货。

点击「阅读原文」获取面试题大全~

java弱_Java 强、弱、软、虚,你属于哪一种?相关推荐

  1. Java:对象的强、软、弱和虚引用

    见:http://zhangjunhd.blog.51cto.com/113473/53092 maven/Java/web/bootstrap/dataTable/app开发QQ群:56686262 ...

  2. Java四大引用(强、软、弱、虚)

    目录 强引用 软引用 弱引用 虚引用 强引用 也是我们平时用得最多的, new 一个对象就是强引用,例如 Object obj = new Object(); 当JVM的内存空间不足时,宁愿抛出Out ...

  3. java 栈_Java实现单链表、栈、队列三种数据结构

    作者:远航 cnblogs.com/yang-guang-zhang/p/13884023.html 一.单链表 1.在我们数据结构中,单链表非常重要.它里面的数据元素是以结点为单位,每个结点是由数据 ...

  4. java木马_Java校验上传图片文件是否含有木马的两种方式

    这两天开发一个app遇到了上传文件的安全问题,在这里记录下来,弥补自己只有鱼的记忆的缺陷,也希望有人能够提供更好的思路去解决文件上传的安全问题. 下面这个类是文件上传的公共方法,ToolUtils判断 ...

  5. java 软引用_Java中弱引用和软引用的区别以及虚引用和强引用介绍

    知道弱引用和软引用的概念与如何使用它们是两码事,引用类在垃圾回收工作的过程中有重要作用.我们都知道垃圾回收器会回收符合回收条件的对象的内存,但并不是所有的程序员都知道回收条件取决于指向该对象的引用类型 ...

  6. java对象的强引用,软引用,弱引用和虚引用

    java对象的强引用,软引用,弱引用和虚引用 标签:              javaoutofmemoryerror生活虚拟机jvmjdk 2011-05-05 21:00             ...

  7. java弱引用弱点_终于有人把Java强、软、弱、虚四种引用知识点整理出来了

    强引用就是指在程序代码之中普遍存在的,指创建一个对象并把这个对象赋给一个引用变量,并没有像其它三种引用一样有一个就具体的类来描述.对于强引用对象,即使内存不足,JVM宁愿抛出OutOfMemoryEr ...

  8. 【Java 虚拟机原理】Java 引用类型 ( 强引用 | 软引用 | 弱引用 | 虚引用 | 静态变量 )

    文章目录 一.静态变量 二. Java 引用类型 ( 强.软.弱.虚 ) 一.静态变量 GC Root 对象 : 线程栈 中的 栈帧 中的 局部变量表 中的 引用对象 ; 方法区 中的 静态引用对象 ...

  9. 【Android 内存优化】Java 引用类型 ( 强引用 | 软引用 | 弱引用 | 虚引用 )

    文章目录 一. Java 引用类型 ( 强.软.弱.虚 ) 二. 软引用代码示例 三. 弱引用代码示例 强引用 ( 不回收 ) > 软引用 ( OOM 前回收 ) > 弱引用 ( GC 必 ...

最新文章

  1. 老王亲述:我的运维心路历程
  2. php创建压缩文件 保存路径,通过php生成zip压缩文件,支持文件和压缩包路径查找...
  3. android toolbar源码解析,深入理解Android 5.0中的Toolbar
  4. 网络配置_CentOS8 网络配置
  5. charles捕获手机端请求数据
  6. Codeforces Round #379 (Div. 2) E. Anton and Tree —— 缩点 + 树上最长路
  7. Linux下执行程序出现 Text file busy 提示时的处理方式
  8. linux系统的手机刷机包,ubuntu系统修复工具-ubuntu手机操作系统刷机包v20.04 官方版 - 极光下载站...
  9. iptables中DNAT、SNAT和MASQUERADE的理解及限速syn
  10. 记录下如何判断错误:no such file or directory
  11. (一)使用 Sliced Sprite 制作 UI 图像
  12. 深入浅出的CSS项目开发总结
  13. 铝电解电容器在电路设计时的使用注意事项
  14. C++ 数组名a、数组名取地址a、数组首地址a[0]、数组指针*p
  15. xSS-Reflected
  16. 永中文档在线转换预览双活实现方案
  17. 雅虎财经股票数据API获取
  18. Tars-C++服务的CI/CD
  19. LeetCode 169 Majority Element(Majority Voting Algorithm)
  20. 小学教师计算机培训课程感言,小学教师信息技术课程学习心得体会

热门文章

  1. 查看sqlserver 2008中性能低下的语句
  2. 关于html5音频如何应用及解决方法?
  3. SQLServer的三种Recovery Model
  4. 对于PHP大型开发框架的看法
  5. 多线程编程(14) - 多线程同步之 WaitableTimer (等待定时器对象)
  6. Python稳基修炼的经典案例14(计算机二级、初学者必会字符格式处理)
  7. 的table数据重复添加_Excel中的超级表Table详细介绍(一)
  8. go 基准测试 找不到函数_初学TDD:测试也能推动开发啦!
  9. Python+django网页设计入门(15):公用模板设计与使用
  10. Python使用递归对任意嵌套列表进行扁平化