关于垃圾回收中的 Roots 对象

2020-07-16 17:21:10 +08:00
 bear2000

最近读了《深入理解 Java 虚拟机》这本书,书中说明了在垃圾回收时,固定可以当做 Roots 的对象,包含以下几种:

  1. 虚拟机栈(栈帧中的本地变量)中引用的对象。
  2. 方法区中类静态属性引用的对象,比如 Java 类的引用类型静态变量。
  3. 方法区中常量引用的对象,比如字符串常量里的引用。
  4. 被同步锁( synchronized )持有的对象。
  5. ......

书中没有说明为什么这些对象可以当做 Roots,作为可达性算法的起始节点。由于面试时被问到且没有答上来,所以很想知道。请教 V 友,求解答。

1712 次点击
所在节点    Java
8 条回复
Dsljlbaby
2020-07-16 18:01:19 +08:00
首先,Java 内存空间被分成那几块?你应该知道 Java 内存空间被分为了程序计数器、本地方法栈、Java 虚拟机栈、堆、方法区这些吧。其次,比如 Java 虚拟机栈中都会存储什么?你应该知道吧,局部变量表主要存储编译期可知的各种基本数据类型( boolean 、byte 、char 、short 、int 、float 、long 、double )和对象引用( reference 类型,它不等同于对象本身,根据不同的虚拟机实现,它可能是一个指向对象起始地址的引用指针,也可能指向一个代表对象的句柄或者其他与此对象相关的位置)和 returnAddress 类型(指向了一条字节码指令的地址)。那么对象引用指针是否可以成为 Root 呢?你可以尝试想想一个对象被创建出来,是如何表示的,比如 Object obj = new Object(),Java 虚拟机会在堆内存中分配一块内存用于存储对象,然后会在 Java 虚拟机栈中分配一个栈桢,存储指向对象的内存地址编号,可以画图理解。obj 就是虚拟机栈(栈帧中的本地变量)中对象引用,也就可以当作一个 Root 。还有强引用、弱引用、虚引用和软引用这些关系
面试时多向面试官展示你思考的过程,而不是答案。当然,这得益于你平时看书时对知识的理解与思考,
bear2000
2020-07-16 18:31:07 +08:00
@Dsljlbaby 可是这貌似只解释了第一点,也就是虚拟机栈(栈帧中的本地变量)中引用的对象。后面几种又是为什么呢?
lazyfighter
2020-07-16 20:49:36 +08:00
你回收了这些 ,别人用啥,你可以想象你的静态变量,突然被虚拟机改变了,你的栈帧指向的变量也变了,还写个屁的程序,都不可信了
wangyanrui
2020-07-16 20:53:48 +08:00
推荐看一下第三版,记得第三版有很详细的描述为什么这些可以作为 GC ROOTS
hellotitan
2020-07-16 20:56:10 +08:00
主要是一些一定认为在此时此刻是活着的对象
bear2000
2020-07-16 21:00:10 +08:00
@wangyanrui 我看的就是第三版啊,没有找到啊,是在哪一页呢?
wangyanrui
2020-07-16 22:16:19 +08:00
@bear2000 是我记错了,翻了翻第三版的目录的确没有,记不清在哪本书上看的了
chen006
2020-07-17 02:47:48 +08:00
垃圾回收是回收不需要的对象,那想想哪些对象是一定需要的呢?那些一定需要的对象引用的对象是不是也需要啊

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/690642

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX