这两天,广州的天气又开始热了起来,又到了小动物交配的季节,啊呸,又到了一个收割 offer 的季节。年底将至,又到了面试的高峰期,JVM 作为Java 程序员面试绕不过的一道坎儿,它又来了,你准备好了吗?

说说引用

面试官 A:小伙几,上篇我们说到了 JVM 收集的两种算法 —— 引用记数法和可达性分析算法,你对这两种算法的理解很清晰,那么这两种算法有一个很重要的点,就是『引用』,其实无论是引用记数法和可达性分析算法都离不开引用,那么你来谈谈引用吧。

我: 这个啊,简单,引用(reference)就是一块内存存储着另一块内存地址(自信脸

面试官 A:说的倒也没错,但是过于片面,那么你能不能详细讲一下引用呢?

我:上白板,我直接上图吧(熟练的拿起马克笔

面试官 A:那么你能不能详细的说一下这四种引用是在什么情况下出现的呢,它们分别代表了什么意义?

我:先说说强引用吧,我们日常中最常见到的就是强引用(拿起桌上的白板,开始手写代码,就像这样的,就属于强引用,它有多强呢,就是只要强引用存在,GC 永远不会对它下手,嗯,你可以理解为就是范闲,皇上的私生子。

String s = "vi的技术博客";
s = "技不可失";

面试官 A:你也看庆余年啊,话说你看过原著没,结局是什么给我剧透剧透呗。

我:咳咳,老哥这样不太好吧,这是我的微信:cm_950825,有什么咱们私聊好吧,不要砸我 offer 收割机的招牌,别人还以为我是靠裙带关系来着(小声BB

面试官 A:那你来说一下软引用吧。

我:我们还是接着来聊庆余年吧,开个玩笑啦,我来一起把软引用和弱引用一起说吧,它们都是用来描述一些非必需的对象,但是弱引用比起软引用来说,更加的弱,怎么说呢,还是看图吧(挥斥方遒的感觉

软引用关联的对象,在系统发生 OOM之前,会把这些对象列入到回收范围之中进行二次回收,如果这次回收仍然没有足够的内存,才会发生 OOM,它是长这样儿式儿的。

Object o = new Object();
SoftReference<Object> soft = new SoftReference<Object>(o);

而弱引用就是个弟弟,只要有 GC,必被回收,这个弟弟是这样的

Object o = new Object();
WeakReference<Object> weak = new WeakReference<Object>(o);

而它们的有一个普遍的应用场景:软引用和弱引用的一个特点是它何时被回收是不可确定的, 因为这是由GC运行的不确定性所确定的. 所以, 一般用它们是有价值被缓存, 而且很容易被重新被构建, 且很消耗内存的对象.

更深的东西我没有再去研究了。。

面试官 A:整挺好,那你来说说最后的这个虚引用吧。

我:虚引用啊,这玩意儿你可以理解为没有这个东西,它的唯一作用就是能在这个对象被 GC 的时候收到一个系统通知。

面试官 A:是这样啊,那行吧,我手机没油了,咱们下次接着聊

面试官上集手机忽然没油了,不知道去哪加了一波油,又回来准备继续和我大战三百回合,尿遁用的如此熟练,一看就不是第一次干这个事情,不是个简单角色啊,我需要提高警惕了。

继续面试

面试官 A :刚刚我的手机没油了,去加了点油(挑眉

我:理解理解,那咱们继续吧?

面试官 A:刚刚我们说到关于引用的一些知识,那么现在有一个问题,我们最开始说到了『可达性分析法』是我们目前正在使用的一个判定方法,那么是否没有连接到 GC Root 的对象都是被要被 GC 回收的呢?

我:话其实也不能这么说(捏衣角),其实还是有挽回的余地的,大道五十,天衍四九。自然会有一丝生机,生机就在于 finalize() 这个神奇的方法中,如果虚拟机发现对象没有连接到 GC Root 上,这个对象就会被打上一个待回收的标签,如果对它不管不顾,它就会抛弃掉,但是如果对它进行一些操作,比如说重写finalize()方法,在里面对它重新进行引用,就可以对这个对象进行最后的救赎。

面试官 A:既然说到了finalize(),你来说说你对这个方法的理解吧~

我:finalize()是Object类中的protected方法,我们通常在子类中继承去完成资源清理的工作,GC 在进行回收的时候回去调用这个方法,但是我们通常不会用这个方法去进行GC,而是去释放一些连接资源或者 IO流。

面试官 A:那么我们为什么通常不会用这个方法去完成 GC 呢?

我:原因啊。。这个我得好好想想,是这样的,finalize()实际上并不能保证资源被回收,因为对象的finalize()方法中可以去做一些操作,使对象重新活过来,这个我刚刚也说过了,而且,由于finalize()方法只会被执行一次,会影响我们的判断,而且它的运行效率非常低,所以我们一般不会用finalize()方法去回收对象。

面试官 A:OK,虽然有些粗略,但是大概说了出来,最后一个问题,你来梳理一下判定一个对象是否为垃圾的流程图吧。

我:好嘞~

  1. 首先,新建一个对象,这个时候对象是处于存活状态的。

  2. 当对象变成 GC Roots 不可达的时候,GC 会去判断是否覆盖了finalize()方法

  3. 如果没有覆盖,直接进行回收。

  4. 如果覆盖了,再去判断对象是否执行过finalize()方法,如果已经执行过,那么也会进行回收。

  5. 如果覆盖且没有执行过finalize()方法,会将这个对象放到一个叫做 F-Queue 的队列中去。

  6. 稍后由一个 JVM 自动建立的、低优先级的 Finalizer 线程去执行

  7. 这里需要注意:这里的执行并不意味着真的会执行完毕,只是告知虚拟机会触发这个方法,并不保证可以运行完毕。

  8. 执行完毕之后,如果对象仍然没有被重新引用(拯救),那么就会被回收。

  9. 如果被重新引用的话,就会被「复活」了。

面试官 A:可以,讲述的还算清楚,我这边考虑一下,你先回去等通知吧

我:好的,老哥再见~

公众号

「 Offer收割机之JVM」:生存还是毁灭的更多相关文章

  1. 「给产品经理讲JVM」:垃圾收集算法

    纠结的我,给我的JVM系列终于起了第三个名字,害,我真是太难了.从 JVM 到 每日五分钟,玩转 JVM 再到现在的给产品经理讲 JVM ,虽然内容为王,但是标题可以让更多的人看到我的文章,所以,历经 ...

  2. 程序人生|从网瘾少年到微软、BAT、字节offer收割机逆袭之路

    有情怀,有干货,微信搜索[三太子敖丙]关注这个不一样的程序员. 本文 GitHub https://github.com/JavaFamily 已收录,有一线大厂面试完整考点.资料以及我的系列文章. ...

  3. 【Java】「深入理解Java虚拟机」学习笔记(1) - Java语言发展趋势

    0.前言 从这篇随笔开始记录Java虚拟机的内容,以前只是对Java的应用,聚焦的是业务,了解的只是语言层面,现在想深入学习一下. 对JVM的学习肯定不是看一遍书就能掌握的,在今后的学习和实践中如果有 ...

  4. 众安「尊享e生」果真牛的不可一世么?

    近日,具有互联网基因的.亏损大户(成立三年基本没盈利,今年二季度末亏损近4亿,你能指望它多厉害?).财产险公司—众安推出“尊享e生”中高端医疗保险(财险公司经营中高端医疗真的很厉害?真的是中高端医疗险 ...

  5. XCActionBar 「Xcode 中的 Alfred」

    下载地址:https://github.com/pdcgomes/XCActionBar 基本命令: (1)「command+shift+8」或者双击「command」键可以打开「动作输入框窗口」 ( ...

  6. Git 执行 「fork 出来的仓库」和「最新版本的原仓库」内容同步更新

    当我们在 GitHub 上 fork 出一个仓库后,如果原仓库更新了,此时怎样才能保证我们 fork 出来的仓库和原仓库内容一致呢?我们一般关注的是仓库的 master(主干分支)的内容,通过以下步骤 ...

  7. 翻译「C++ Rvalue References Explained」C++右值引用详解 Part1:概述

    本文系对「C++ Rvalue References Explained」 该文的翻译,原文作者:Thomas Becker. 该文较详细的解释了C++11右值引用的作用和出现的意义,也同时被Scot ...

  8. 苹果搜索广告后台大揭秘,最全最细致详解,手把手设置教程「后附官方视频」-b

    WWDC2016 搜索广告分会视频和 PPT 发布了,ASO100 带开发者第一时间了解 Search Ads 后台设置(文末有原声视频). 首先介绍一下搜索广告的模式和竞价规则 广告模式为 CPT( ...

  9. 被「李笑来老师」拉黑之「JavaScript微博自动转发的脚本」

    故事的背景如下图,李笑来 老师于10月19日在 知乎Live 开设 一小时建立终生受用的阅读操作系统 的讲座,他老人家看到大家伙报名踊跃,便在微博上发起了一个 猜数量赢取iPhone7 的活动. 因为 ...

随机推荐

  1. java使用jackson生成和解析JSON

    java使用jackson生成和解析JSON 1.导包 2.生成json和解析json package test; import com.fasterxml.jackson.core.JsonProc ...

  2. 1122 Hamiltonian Cycle (25 分)

    1122 Hamiltonian Cycle (25 分) The "Hamilton cycle problem" is to find a simple cycle that ...

  3. kettle_errot_karafLifecycleListenter

    使用kettle 6.1 通过命令行批量执行作业的过程中,发现偶尔有作业执行时间会变慢几分钟,查看日志发现改作业开始就报了一个错 报错之后才会继续下面的作业,虽然不影响最终作业执行结果,但也延误了一些 ...

  4. RxJava 2.x 源码分析

    本次分析的 RxJava 版本信息如下: 12 implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'implementation 'io.reac ...

  5. linux 的uuid码

    在提到这个之前,有个概念,就是什么是uuid呢? UUID码全称是通用唯一识别码 (Universally Unique Identifier, UUID),它 是一个软件建构的标准,亦为自由软件基金 ...

  6. Android系统使用Shell脚本预装apk

    客户需求:需要在Android系统预安装一个或者若干个apk,客户可以选择自行卸载并且卸载后系统再次启动并不会再次自动安装. 考虑到需要批量安装应用,我这里考虑到使用灵活的shell脚本.shell脚 ...

  7. JSON parse error: Cannot deserialize value of type `java.util.Date` from String

    DateTimePicker + @DateTimeFormat("yyyy-MM-dd HH:mm:ss")日期格式转换异常 最近在做的一个项目使用的日期格式是yyyy-MM-d ...

  8. 2——PHP defined()函数

    */ * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:text.cpp * 作者:常轩 * 微信公众号:Worldhe ...

  9. React之mockjs+sass+生命周期函数

    mdn W3C标准网站 运行sass cnpm i -D node-sass-chokidar npm-run-all rem单位设置 <script> //rem单位设置 documen ...

  10. VM安装Linux Centos7.0虚拟机

    一.准备工作 1.安装VMware 官网https://www.vmware.com/cn.html 2.准备centos7的镜像文件 官网下载链接:http://isoredirect.centos ...