面试官:GC是如何快速枚举根节点的?

简介: 面试官:GC是如何快速枚举根节点的?

image.png

Java一个优点就是GC(Garbage Collection),虽然它能帮我们管理内存,但是它工作的时候会STW(Stop the World)。也就是停止所有的工作线程,"你们先别干活,我先来清理清理垃圾!"。


那就出问题了啊,你想想比如你在玩游戏的时候,电脑来个STW停个几秒钟时间,清理下垃圾。你可能就会****,你队友可能也会***。


但是现在常用的一些垃圾收集器都得STW,虽然各种垃圾收集器已经各种绞尽脑汁减少STW的时间,但是做不到避免STW。具体的各种垃圾收集器的对比下次单独写一篇文章。


今天先来讲述一下GC是如何快速枚举根节点。在HotSpot虚拟机中,是通过可达性分析来判断此对象是否需要回收的。那可达性分析就需要找到“源头”,也就是根节点。

通过枚举一个一个根节点(GC Roots),然后顺藤摸瓜一路摸下来,然后没摸到的那些对象就把它咔嚓回收了。那这个顺藤摸瓜的过程就必须让世界停止,也就是那些工作线程都得停了,你想想如果不STW那对象引用关系变来变去的,垃圾收集器得怎么咔嚓对象啊,容易咔嚓错了,那咱们使用者不就急眼了啊。所以枚举根节点时STW不可避免,所以只能让STW尽量的短。


根节点主要在全局性的引用(常量、类静态属性)和执行上下文(栈帧中的本地变量表)中。那我们如果要一个一个的找过去就很慢。并且我们的HotSpot又是准确性GC,也就是它需要知道某个位置上的某个数据的类型,类型是准确的。这样它就能准确的知道这块数据类型是不是它关心的指针也就是引用啦!


在HotSpot中是用了一种叫OopMap的结构来存放一个对象内什么偏移量上是什么类型的数据。在类加载过程中就会进行记录。可以把OopMap理解为一个附加信息,或者说一件衣服的吊牌,咱们看吊牌就知道这衣服啥做的。所以GC在扫描的时候就可以直接看这些“吊牌”来知道信息了。


JIT编译的时候也会在一些特定的位置记录下OopMap,记录了执行到该方法的某条指令的时候,栈上和寄存器里哪些位置是引用,每个方法可能会有好多个OopMap,这是根据特定位置来决定的,这个特定位置会把这个方法分会好几块,每一块都有一个OopMap。


这些特定的位置主要在:


1、方法临返回前/调用方法的call指令后


2、循环的末尾


3、可能抛出异常的地方


这些特定的位置也叫安全点(Safepoint)。


之所以要在特定的位置才记录OopMap,是因为如果对每条指令都记录一下的话,那就会需要大量的空间,提高了GC的空间成本,所以用一些比较关键的点来记录就能有效的缩小记录所需的空间。


因此GC不是随时随地来的,得到达安全点时才可以开始GC


平时OopMap是压缩在内存中,只要当要GC的时候才会解压出来,然后开始遍历来扫描对应的偏移量。


对于JNI(Java Native Interface)方法,因为本地方法和解释器、JIT编译器没啥关系,所以就没有OopMap。它的引用是加了个中间层一样的,就是句柄,也就是引用不是直接指向堆中的对象,而是引用指向句柄,句柄指向堆中对象。所以GC直接扫描句柄就行了,不需要扫描栈帧。



相关文章
|
10月前
|
JavaScript 测试技术 索引
面试题-TS(七):如何定义枚举(enums)并使用它们?
在TypeScript中,枚举(Enums)是一种用于定义命名常量集合的数据类型。枚举允许我们为一组相关的常量赋予有意义的名字,并在代码中以更直观的方式使用它们。通过使用枚举,我们可以简化代码,提高可读性,并减少错误。
Java2EE练习及面试题_chapter10枚举类与注解
Java2EE练习及面试题_chapter10枚举类与注解
|
存储 安全 Java
【Java面试】枚举从使用到原理
【Java面试】枚举从使用到原理
113 0
【Java面试】枚举从使用到原理
|
设计模式 安全 Java
面试官:说说对单例模式的理解,最后的枚举实现我居然不知
说起单例模式(Singleton Pattern),想必大家都不不会陌生,它是 Java 中最简单的设计模式之一,属于创建型模式的一种,它提供了一种创建对象的最佳方式。 这种模式的意义在于保证一个类仅有一个实例,并提供一个访问它的全局访问点,避免重复的创建对象,节省系统资源。
|
人工智能
2017广东工业大学程序设计竞赛决赛 题解&源码(A,数学解方程,B,贪心博弈,C,递归,D,水,E,贪心,面试题,F,贪心,枚举,LCA,G,dp,记忆化搜索,H,思维题)
心得: 这比赛真的是不要不要的,pending了一下午,也不知道对错,直接做过去就是了,也没有管太多! Problem A: 两只老虎 Description   来,我们先来放松下,听听儿歌,一起“唱”。
1516 0
|
1月前
|
存储 安全 Java
大厂面试题详解:java中有哪些类型的锁
字节跳动大厂面试题详解:java中有哪些类型的锁
60 0
|
2月前
|
Java 程序员
java线程池讲解面试
java线程池讲解面试
66 1
|
3天前
|
Java
【Java多线程】面试常考 —— JUC(java.util.concurrent) 的常见类
【Java多线程】面试常考 —— JUC(java.util.concurrent) 的常见类
14 0
|
3天前
|
安全 Java 程序员
【Java多线程】面试常考——锁策略、synchronized的锁升级优化过程以及CAS(Compare and swap)
【Java多线程】面试常考——锁策略、synchronized的锁升级优化过程以及CAS(Compare and swap)
7 0
|
19天前
|
Java 调度
Java面试必考题之线程的生命周期,结合源码,透彻讲解!
Java面试必考题之线程的生命周期,结合源码,透彻讲解!
42 1