Java面试题冲刺第二十九天--JVM3

作者:_陈哈哈 时间:2021-05-24 05:34:26 

目录
  • 面试题1:如何判断对象是否存活

    • 1.引用计数算法

    • 2.可达性分析算法

  • 面试题2:哪些对象可以作为GC Roots?

    • 面试题3:你了解的对象引用方式都有哪些?

      • 1 强引用

      • 2 软引用

      • 3 弱引用

      • 4 虚引用

    • 总结

      面试题1:如何判断对象是否存活

      对于判断对象是否存活,主要是两种基本算法,引用计数和可达性分析,目前java主要采用的是可达性分析算法

      1.引用计数算法

      判断对象是否存活的方式如:在对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加一;当引用失效时,计数器值就减一;任何时刻计数器为零的对象就是不可能再被使用的。

      其优点是实现简单,判定效率高;缺点是该算法有很多例外情况要考虑,必须要配合大量额外处理才能保证正确地工作,且存在一个基本的难题,也就是很难处理循环引用关系。

      2.可达性分析算法

      其原理简单来说,就是将对象及其引用关系看作一个图,通过一系列称为GC Roots的根对象作为起始节点集,从这些节点开始,通过引用关系向下搜索,搜索过程所走过的路径称为引用链(Reference Chain),如果一个对象和 GC Roots 之间不可达,也就是不存在引用链条,那么即认为是可回收对象。JVM会把虚拟机栈和本地方法栈中正在引用的对象、静态属性引用的对象和常量,作为 GC Roots。

      Java面试题冲刺第二十九天--JVM3

      如图所示,对象object 5、object 6、object 7虽然互有关联,但是它们到GC Roots是不可达的, 因此它们将会被判定为可回收的对象。

      面试题2:哪些对象可以作为GC Roots?

      在Java技术体系里面,固定可作为GC(Garbage Collector) Roots的对象包括以下几种:

      Java面试题冲刺第二十九天--JVM3

      常说的GC(Garbage Collector) roots,特指的是垃圾收集器的根对象(GC Root Object),也叫作称为GC垃圾回收根(GC Root),GC会收集那些不是GC roots且没有被GC roots引用的对象清理掉。

      一个对象可以属于多个root,GC root存在几下种:

      • 虚拟机栈中引用 的对象

        • 如各个线程被调用的方法堆栈中使用到的 参数、局部变量、临时变量等。

      • 方法区中类静态属性引用的对象

        • 如Java 类的引用类型静态变量

      • 方法区中常量引用的对象

        • 如字符串常量池(String Table) 里的引用

      • 本地方法栈内 JNI(通常说的本地方法)引用的对象

      • 所有被同步锁 (synchronized关键字) 持有的对象

      • Java 虚拟机内部的引用

        • 如基本数据类型对应的Class对象,一些常驻的异常对象(比如 NullPointExcepiton、OutOfMemoryError)、系统类加载器等。

      • 反映 Java 虚拟机内部情况的 JMXBean、JVMTI 中注册的回调、本地代码缓存等。

      • 除了固定的 GC Roots 集合以外,根据用户所选用的垃圾收集器以及当前回收的内存区域不同,还可以有其他对象 临时性 地加入,共同构成完整 GC Roots 集合。

      面试题3:你了解的对象引用方式都有哪些?

      该回答来自极客时间《Java核心技术面试精讲第四讲》的评论部分。

      在Java语言中,除了基本数据类型外,其他的都是指向各类对象的对象引用;Java中根据其生命周期的长短,将引用分为强引用、弱引用、软引用、虚引用4类。

      1 强引用

      我们平常典型编码Object obj = new Object()中的obj就是强引用。通过关键字new创建的对象所关联的引用就是强引用。 当JVM内存空间不足,JVM宁愿抛出OutOfMemoryError运行时错误(OOM),使程序异常终止,也不会靠随意回收具有强引用的存活对象来解决内存不足的问题。对于一个普通的对象,如果没有其他的引用关系,只要超过了引用的作用域或者显式地将相应(强)引用赋值为null,就是可以被垃圾收集的了,具体回收时机还是要看垃圾收集策略。

      2 软引用

      软引用通过SoftReference类实现。

      软引用的生命周期比强引用短一些。只有当 JVM 认为内存不足时,才会去试图回收软引用指向的对象:即JVM 会确保在抛出OutOfMemoryError之前,清理软引用指向的对象。软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被垃圾回收器回收,Java虚拟机就会把这个软引用加入到与之关联的引用队列中。后续,我们可以调用ReferenceQueue.poll()方法来检查是否有它所关心的对象被回收。如果队列为空,将返回一个null,否则该方法返回队列中前面的一个Reference对象。

      应用场景:软引用通常用来实现内存敏感的缓存。如果还有空闲内存,就可以暂时保留缓存,当内存不足时清理掉,这样就保证了使用缓存的同时,不会耗尽内存。

      3 弱引用

      弱引用通过WeakReference类实现。

      弱引用的生命周期比软引用短。在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。由于垃圾回收器是一个优先级很低的线程,因此不一定会很快回收弱引用的对象。弱引用可以和一个引用队列(ReferenceQueue)联合使用,如果弱引用所引用的对象被垃圾回收,Java虚拟机就会把这个弱引用加入到与之关联的引用队列中。

      应用场景:弱引用同样可用于内存敏感的缓存。

      4 虚引用

      虚引用也叫幻象引用,通过PhantomReference类来实现。

      无法通过虚引用访问对象的任何属性或函数。幻象引用仅仅是提供了一种确保对象被 finalize 以后,做某些事情的机制。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收。虚引用必须和引用队列 (ReferenceQueue)联合使用。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之关联的引用队列中。


      ReferenceQueue queue = new ReferenceQueue ();
      PhantomReference pr = new PhantomReference (object, queue);

      程序可以通过判断引用队列中是否已经加入了虚引用,来了解被引用的对象是否将要被垃圾回收。如果程序发现某个虚引用已经被加入到引用队列,那么就可以在所引用的对象的内存被回收之前采取一些程序行动。

      应用场景:可用来跟踪对象被垃圾回收器回收的活动,当一个虚引用关联的对象被垃圾收集器回收之前会收到一条系统通知。

      来源:https://blog.csdn.net/qq_39390545/article/details/120202555

      标签:Java,JVM,面试题
      0
      投稿

      猜你喜欢

    • Java 数据结构与算法系列精讲之哈希算法实现

      2022-01-10 23:56:07
    • SpringMVC bean加载控制的实现分析

      2023-08-08 18:46:19
    • java与js代码互调示例代码

      2022-11-09 20:19:05
    • Spring+SpringMVC+MyBatis深入学习及搭建(一)之MyBatis的基础知识

      2021-09-27 15:12:59
    • Java由浅入深刨析继承

      2023-11-23 08:04:24
    • JDK8中的HashMap初始化和扩容机制详解

      2023-11-25 10:06:44
    • 在IDEA里gradle配置和使用的方法步骤

      2023-11-23 16:07:58
    • java生成指定范围随机数的多种代码

      2023-04-28 07:51:15
    • 解决java文件流处理异常 mark/reset not supported问题

      2022-10-05 14:28:08
    • Java hashCode原理以及与equals()区别联系详解

      2023-03-04 15:37:56
    • springcloud整合seata的实现代码

      2022-04-26 23:49:49
    • C#语言中字符类char的使用方法(总结)

      2022-09-04 17:25:43
    • Java数据结构中堆的向下和向上调整解析

      2022-01-02 07:34:58
    • java项目中使用 Lombok遇到的问题小结

      2023-09-11 02:09:53
    • 详解Java虚拟机管理的内存运行时数据区域

      2023-12-04 01:32:35
    • 浅析Java线程的中断机制

      2023-11-19 20:11:50
    • android采用FFmpeg实现音频混合与拼接剪切

      2023-10-04 06:51:24
    • openFeign服务之间调用保持请求头信息处理方式

      2022-11-07 23:45:21
    • mall整合SpringTask实现定时任务的方法示例

      2023-09-15 18:08:08
    • SpringBoot中 Jackson 日期的时区和日期格式问题解决

      2021-09-06 19:37:50
    • asp之家 软件编程 m.aspxhome.com