智畅行科技资讯网
首页 > 科技 > 连引用都答不上 凭什么说你是Java服务端开发

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

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

经常会有朋友找我吹水,最近就说到了一个面试题

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

因此打算以该面试题为例子,写篇文章说说在Java中引用是什么以及怎么用。

【划重点:给你三秒钟时间思考,如果是你,该如何回答面试官的这个问题呢】

引用是什么

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

FinalReference 强引用

SoftReference 软引用

WeakReference 弱引用

PhantomReference 虚引用

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

方便Jvm进行垃圾回收

方便开发人员使用,开发人员可以灵活的决定某些物件的生命周期

日常开发如何使用

学以致用,那么这几个引用在日常中我们如何进行使用呢?

接下来我会给出相关demo!!!

FinalReference 强引用

类似于 Object o = new Object 这类的引用,建立一个物件后,该引用会被储存在JVM栈中,而且只要强引用存在,垃圾回收器就不会回收掉被引用的物件。

日常使用

强引用的例子比比皆是,因为在日常开发中我们是会经常去new一个物件的,而该new出来的物件便是强引用的,也就是说只要该引用存在,垃圾回收器就不会回收掉。

【划重点:JVM怎么知道引用在不在?】

SoftReference 软引用

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

给出demo

通过注释便可以知道,我这里例项化了多个大物件,然后放入softReferences阵列中,之后便遍历打印出其中的物件的命名,打印结果如下

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

日常使用

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

WeakReference 弱引用

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

给出demo

程式码很简短,就是先构建一个弱引用物件,然后在gc前先打印出来证明它存在过,之后手动呼叫gc,再次打印,可以看出已经没了。执行结果如下

PhantomReference 虚引用

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

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

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

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

ReferenceQueue 引用伫列

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

那么它有何作呢?

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

给出demo

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

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

和Reference相关的概念

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

active 一般来说内存一开始被分配的状态,而当被引用的物件的可达性发生变化后gc就会将引用放入pending伫列并将其状态改为pending状态。

pending 指的是准备要被放进pending伫列的物件。

enqueue 指的是物件的内存已经被回收了。

inactive 这是最终的状态,不能再变为状态。

JVM怎么知道引用在不在

关于JVM怎么知道引用在不在,这就涉及到了JVM的可达性分析算法了

JVM的可达性分析算法的简单思路就是通过一系列GC Roots作为出发点,向下搜寻,搜寻所走过的路径称为引用链,当一个物件到GC Roots没有任何引用链,即表明从GC Roots到这个物件不可达时,证明此物件不可用,可被回收。如下图所示

物件4、5、6都是可被回收的。

那么问题来了,哪些物件可以作为GC Roots呢?

这里给出几个,如下

虚拟机器栈中引用的物件

方法区中类静态属性引用的物件

方法区中常量引用的物件

本地方法栈JNI引用的物件

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

最后的最后

该篇文章基本解答了【谈谈对Java中几种引用的理解】,如果想要更深入的研究,就要从源代码入手了解了。

下次遇见这种面试题,基本上就不慌了,因为实际上只要认真看完该篇文章并且记住几个关键的地方,基本上就不会被面试官问倒了,并且该篇文章后面也解答了【JVM怎么知道引用在不在】和【哪些物件可以作为GC Roots】的问题。

标签:

上一篇 目录 下一章

猜你喜欢

2022年世界最新科技成果 鳄鱼皮iPho...
鳄鱼皮iPhoneX见过没?苹果终于出新款式 不同的人对于手机的需求也有所区别,对于学生来说手机的要求可能是性价比高为首选,老年人对于手机的要求可能是实用...
科技名言简短一点 魔兽世界服梦回...
魔兽世界服梦回70?冲级去血色修道院 虎牙阿诺错过迈恩怀特_副本 前段时间,魔兽世界官方释出公告表示服测试服的等级上限将从30级提高到40级,而在开服之后...
牙签发射器 魔兽世界天赋只...
魔兽世界:天赋只能选治疗?60年代德鲁伊套装大解析 60年代作为唯一一个万金油职业,我们可怜的德鲁伊地位和套装一样效能低下。既不能当坦克(后期安其拉时代修...
2021年最新科技成果 魅族联合谷歌将...
魅族联合谷歌将推出AndroidGo手机 4月22日,魅族在乌镇发布了15周年旗舰机魅族15系列。而现在,魅族全球营销负责人Ard Boudeling在推...

强力推荐