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

简介: Java面试题:哪些对象可以作为GC Roots?
+关注继续查看

Java是托管运行对语言,内存对分配和回收是自动进行对。 那么JVM如何确定哪些内存可以被回收呢?这里面是有特定对算法的。
1、GC自动垃圾收集?
Java虚拟机(JVM)垃圾回收GC任务自动确定Java应用程序不再使用的内存并将该内存回收以用于其他用途。
由于内存是在JVM中自动回收的,因此Java开发人员不必考虑复杂的内存释放工作,基本不需要显式释放未使用的内存对象。
类似与自己买菜做饭洗碗和专有保姆买菜做饭洗碗的区别。
工作还是要有人做,只是把复杂琐碎的GC工作交给其他线程来做。
好处就是:省事。解放码农的双手,去干其他的开发工作。
1、GC垃圾回收算法
GC垃圾回收的规则和方法很多,Java经历了20多年的发展,还在不断进化。GC算法也多种多样。这里比较成熟的CMS。还有比较新的算法G1。无论何种算法,都有一个最重要的问题:
如何认定某个对象可以被GC垃圾回收?
image
GC回收垃圾操作基于以下假设前提:Java中大多数对象都是短命的,并且可以在创建后不久将其回收。
由于未引用的对象会自动从堆内存中删除,因此GC使Java的内存效率更高。
GC自动垃圾回收是查看堆内存,识别正在使用的对象和未使用的对象以及删除未使用的对象的过程。
使用中的对象或引用的对象意味着程序的某些部分仍维护着指向该对象的指针。
程序的任何部分都不再引用未使用的对象或未引用的对象。 因此,GC可以回收未引用对象使用的内存。
image
双重释放会导致错误,当程序尝试释放已经释放并且可能已经重新分配的内存区域时,会发生双重释放错误。
内存泄露,是经常面试考察的问题,某些类型的内存泄漏,其中程序无法释放已变得无法访问的对象占用的内存,这可能导致OOM错误内存耗尽。
很多开源工具可以帮助分析Java的内存泄露问题。
2、GC Root作用
GC Root是很特殊的对象,在GC进行垃圾回收之前,要判断对象是否可以被回收。这里判断的标准需要有依据。就是一个对象如何确定是不是被引用,或者被使用。
image
在Java中,有一些特殊的对象称为GC垃圾回收根(GC Root)。 它们充当垃圾收集标记机制的根对象(GC Root Object)。
GC Root Object可以从Java堆的外部访问,也就是不受GC的自动回收管制。可以理解为有免死金牌的Java对象。GC这套法律体系约束不了它们。
3、GC Roots类型
那么有哪些类似可以作为GC Roots类型呢?我们来看一下下面的类型列表:

类型 说明
System Class 类型 由引导程序/系统类加载器加载的类型。例如,rt.jar中的所有内容(如java.util。*)。
JNI Local 类型 本机原生代码中的局部变量,例如用户定义的JNI代码或JVM内部代码。
JNI Global 类型 本机原生代码中的全局变量,例如用户定义的JNI代码或JVM内部代码。
Thread Block 类型 从当前活动的线程块引用的对象。
Thread 类型 已经启动运行的线程 thread.
Busy Monitor 类型 忙碌的监视器代码,调用了wait()或notify()或已同步的所有代码。
Java Local 类型 局部变量。例如,输入参数或仍在线程堆栈中的方法的局部创建对象。
Native Stack 类型 本机原生代码中的输入或输出参数,例如用户定义的JNI代码或JVM内部代码。
Finalizable 类型 可终结对象,队列中等待其终结器运行的对象.
Unfinalized 类型 未终结对象,具有finalize方法但尚未完成且尚未在终结器队列中的对象.
Unreachable 类型 不可达对象,无法从任何其他根访问的对象,MAT使用.
Java Stack Frame 类型 Java栈框架,持有局部变量。解析Dump时使用.
Unknown 类型 根类型未知对象。MAT分析Dump文件时的特殊类型,归类不可知类型.

像系统类型、JNI代码、运行的线程、同步区的对象等还是比较好理解的,基本是不受管控。Finalizable、Unfinalized和Unreachable都是GC回收中比较特殊的对象。剩下的Unknown可以理解为MAT分析过程中其他不可知对象准备的Root类型。
参考资料:
1、https://help.eclipse.org/2020-03/index.jsp?topic=%2Forg.eclipse.mat.ui.help%2Fconcepts%2Fgcroots.html&cp=37_2_3
2、https://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html

目录
相关文章
|
2天前
|
Java
Java对象
Java对象是Java编程语言中的核心概念,是通过类实例化得到的具体实体,具有属性和方法,可以看作现实世界中的事物、概念或抽象概念的表示。Java对象是由我们自己定义的类来创建出来的,对象实际上就是类的具体实现。没有类就没有对象,一个类可以创建出多个对象。Java对象也具有它的状态和行为,只不过需要我们自己抽象出来。简单的来说就是模仿现实世界然后用语言创建出来。
71 0
|
3天前
|
Java
Java深拷贝和浅拷贝Map对象
Java深拷贝和浅拷贝Map对象
8 0
|
5天前
|
存储 安全 Java
【Java基础】Java对象的生命周期
【Java基础】Java对象的生命周期
36 0
|
6天前
|
Java 编译器 程序员
Java 教程 (Java 对象和类)
Java 教程 (Java 对象和类)
|
6天前
|
Java 编译器 数据安全/隐私保护
|
8天前
|
存储 Java
Java对象数据结构介绍
Java对象是一种复杂的数据结构,它允许我们在内存中存储一系列属性和方法。这些属性和方法可以在程序运行期间被访问和修改,以实现特定的功能和操作。
|
9天前
|
Java
Excel解析为java对象
Excel解析为java对象
10 0
|
18天前
|
Java
JAVA对象的转型
JAVA对象的转型
11 0
|
21天前
java-文件对象
文件对象
17 0
|
28天前
|
存储 Java 程序员
深度理解JAVA中的栈、堆、对象、方法区、类和他们之间的关系
1.方法:当一个方法执行时,该方法都会建立自己的内存栈,在该方法内定义的变量将会逐个放入内存栈中,随着方法执行结束,该方法的内存栈也将自然销毁.因此,所有在方法中定义的局部变量都是放在栈内存中的。
深度理解JAVA中的栈、堆、对象、方法区、类和他们之间的关系
推荐文章
更多