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

相关文章
|
6月前
|
设计模式 网络协议 数据可视化
Java 设计模式之状态模式:让对象的行为随状态优雅变化
状态模式通过封装对象的状态,使行为随状态变化而改变。以订单为例,将待支付、已支付等状态独立成类,消除冗长条件判断,提升代码可维护性与扩展性,适用于状态多、转换复杂的场景。
893 157
|
7月前
|
算法 Java
50道java集合面试题
50道 java 集合面试题
|
9月前
|
Java 数据库连接 数据库
Java 相关知识点总结含基础语法进阶技巧及面试重点知识
本文全面总结了Java核心知识点,涵盖基础语法、面向对象、集合框架、并发编程、网络编程及主流框架如Spring生态、MyBatis等,结合JVM原理与性能优化技巧,并通过一个学生信息管理系统的实战案例,帮助你快速掌握Java开发技能,适合Java学习与面试准备。
409 2
Java 相关知识点总结含基础语法进阶技巧及面试重点知识
|
8月前
|
缓存 安全 Java
Java反射机制:动态操作类与对象
Java反射机制是运行时动态操作类与对象的强大工具,支持获取类信息、动态创建实例、调用方法、访问字段等。它在框架开发、依赖注入、动态代理等方面有广泛应用,但也存在性能开销和安全风险。本文详解反射核心API、实战案例及性能优化策略,助你掌握Java动态编程精髓。
|
7月前
|
算法 Java
50道java基础面试题
50道java基础面试题
|
8月前
|
存储 人工智能 JavaScript
Java从作用域到对象高级应用​
本内容详细讲解了JavaScript中的作用域类型(函数作用域、块作用域、全局作用域)、作用域链、垃圾回收机制、闭包、变量提升、函数参数、数组方法、内置构造函数、对象高级知识、原型链、对象赋值、深浅拷贝、递归、异常处理及this指向等内容,全面覆盖JS核心概念与编程技巧。
99 0
|
9月前
|
存储 Java
Java对象的内存布局
在HotSpot虚拟机中,Java对象的内存布局分为三部分:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)。对象头包含Mark Word、Class对象指针及数组长度;实例数据存储对象的实际字段内容;对齐填充用于确保对象大小为8字节的整数倍。
183 0
|
存储 Java
【IO面试题 四】、介绍一下Java的序列化与反序列化
Java的序列化与反序列化允许对象通过实现Serializable接口转换成字节序列并存储或传输,之后可以通过ObjectInputStream和ObjectOutputStream的方法将这些字节序列恢复成对象。
|
存储 算法 Java
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
本文详解自旋锁的概念、优缺点、使用场景及Java实现。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
下一篇
开通oss服务