博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
连引用都答不上,凭什么说你是Java服务端开发
阅读量:5282 次
发布时间:2019-06-14

本文共 2127 字,大约阅读时间需要 7 分钟。

谈谈对Java中几种引用的理解。

因此打算以该面试题为例子,写篇文章说说在Java中引用是什么以及怎么用。 【划重点:给你三秒钟时间思考,如果是你,该如何回答面试官的这个问题呢】

引用是什么

【划重点】在Java中引用包括:

  • FinalReference 强引用
  • SoftReference 软引用
  • WeakReference 弱引用
  • PhantomReference 虚引用

那么为什么会提供这四种引用呢,主要原因有:

  • 方便Jvm进行垃圾回收
  • 方便开发人员使用,开发人员可以灵活的决定某些对象的生命周期

日常开发如何使用

学以致用,那么这几个引用在日常中我们如何进行使用呢? 接下来我会给出相关demo!!!

FinalReference 强引用

类似于 Object o = new Object() 这类的引用,创建一个对象后,该引用会被保存在JVM栈中,而且只要强引用存在,垃圾回收器就不会回收掉被引用的对象。

日常使用

强引用的例子比比皆是,因为在日常开发中我们是会经常去new一个对象的,而该new出来的对象便是强引用的,也就是说只要该引用存在,垃圾回收器就不会回收掉。 【划重点:JVM怎么知道引用在不在?】

SoftReference 软引用

软引用关联的对象,在内存不够的情况下,会把这些软引用关联的对象列入垃圾回收范围中,然后进行回收,也就是说软引用并非是完全安全的,在内存不够的情况下是会被垃圾回收器回收掉的。

给出demo

连引用都答不上,凭什么说你是Java服务端开发

 

通过注释便可以知道,我这里实例化了多个大对象,然后放入softReferences数组中,之后便遍历打印出其中的对象的命名,打印结果如下

连引用都答不上,凭什么说你是Java服务端开发

可以通过结果看出,前面四个对象因为内存不够而被垃圾回收器回收了。

日常使用

在我司的项目中,部分是使用软引用来保存从数据库中取出的数据,具体是做了一个中间层的封装,该中间层的作用就是在get出数据的时候会去判断数据是否为null,如果是为null再次从数据库读取,读取后再放入软引用的集合中,这样的做法是可以避免内存溢出。

WeakReference 弱引用

弱引用比软引用更弱,被弱引用关联的对象只能存活到发生下一次垃圾回收之前,也就是说当发生GC时,无论当前内存是否足够,都会被回收掉。

给出demo

连引用都答不上,凭什么说你是Java服务端开发

 

代码很简短,就是先构建一个弱引用对象,然后在gc前先打印出来证明它存在过,之后手动调用gc,再次打印,可以看出已经没了。运行结果如下

连引用都答不上,凭什么说你是Java服务端开发

 

PhantomReference 虚引用

虚引用和上面不同的地方在于,一个对象是否有虚引用的存在,完全不会对其生存时间构成如何影响,并且也无法通过虚引用来获取一个对象的实例,也就是说跟没有引用与之关联一样,在任何时候都可能被垃圾回收器回收。

那么这样就很容易产生疑问了,虚引用的作用又是什么呢?

作用就是能在这个对象被收集器回收时收到一个系统通知,实现追踪垃圾收集器的回收动作,比如在对象被回收的时候,会调用该对象的finalize方法。

在给出相关demo前,要先介绍一个

ReferenceQueue 引用队列

ReferenceQueue 引用其实也可以归纳为引用中的一员,可以和上述三种引用类型组合使用【软引用、弱引用、虚引用】。

那么它有何作呢?

在创建Reference时,手动将Queue注册到Reference中,而当该Reference所引用的对象被垃圾收集器回收时,JVM会将该Reference放到该队列中,而我们便可以对该队列做些其他业务,相当于一种通知机制。

给出demo

连引用都答不上,凭什么说你是Java服务端开发

 

可以从demo中看出队列的用法,运行打印结果如下

连引用都答不上,凭什么说你是Java服务端开发

 我们可以从结果中看到先是从引用中get出来的对象为null,证明上面说的无法通过虚引用来获取一个对象的实例,并且在回收后会被放入队列中。

和Reference相关的概念

首先为了方便JVM进行管理,Reference是有状态的,可以分为以下四种状态

  • active 一般来说内存一开始被分配的状态,而当被引用的对象的可达性发生变化后gc就会将引用放入pending队列并将其状态改为pending状态。
  • pending 指的是准备要被放进pending队列的对象。
  • enqueue 指的是对象的内存已经被回收了。
  • inactive 这是最终的状态,不能再变为其它状态。

JVM怎么知道引用在不在

关于JVM怎么知道引用在不在,这就涉及到了JVM的可达性分析算法了 JVM的可达性分析算法的简单思路就是通过一系列GC Roots作为出发点,向下搜索,搜索所走过的路径称为引用链,当一个对象到GC Roots没有任何引用链,即表明从GC Roots到这个对象不可达时,证明此对象不可用,可被回收。如下图所示

连引用都答不上,凭什么说你是Java服务端开发

 

对象4、5、6都是可被回收的。 那么问题来了,哪些对象可以作为GC Roots呢? 这里给出几个,如下

  • 虚拟机栈中引用的对象
  • 方法区中类静态属性引用的对象
  • 方法区中常量引用的对象
  • 本地方法栈JNI引用的对象

具体的想要深入研究的可以自行百度&谷歌,或者等我后面深入分析。

转载于:https://www.cnblogs.com/CQqf2019/p/11088151.html

你可能感兴趣的文章
设置了word-break:break-all,末尾有中文标点会提前换行的问题
查看>>
安装以及构建SSIS
查看>>
设计模式-命令模式
查看>>
SharePoint 2013的100个新功能之内容管理(一)
查看>>
2013 - Lost connection to MySQL server at 'reading initial communication packet' 错误解决
查看>>
Openwrt 初探
查看>>
拉格朗日乘子
查看>>
less语法
查看>>
如何重启IIS进程
查看>>
PowerDesigner中Table视图同时显示Code和Name
查看>>
JavaScript parser
查看>>
Jenkins参数化构建插件,实现构建前输入自定义参数
查看>>
2、Java并发性和多线程-多线程的优点
查看>>
HTTP协议初识
查看>>
如何制作漂亮的母版
查看>>
mysql存储过程的参数名不要跟字段名一样 (血淋淋的代价)
查看>>
J2EE面试题集锦(附答案)
查看>>
2013项目总结
查看>>
Android 将文件保存到SD卡中
查看>>
作业三-----词频统计
查看>>