Java GC面试必问三件套有哪些

 更新时间:2026年06月08日 09:51:43   作者:fengxin_rou  
GC是垃圾收集器,Java程序员不用担心内存管理,因为垃圾收集器会自动进行管理,这篇文章主要介绍了Java GC面试必问三件套有哪些的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下

java的gc 机制你知道哪些?

gc机制是Java的垃圾回收机制,指在Java中对象没有被引用从而被回收释放资源的一种机制

可以从哪些对象可以被回收、回收的方式有哪些、回收器有哪些这三个方面来分析gc

哪些对象可以被回收?

通常用可达性分析算法来确定哪些对象可以被回收,当一个对象没有被任何一个GC Root(比如虚拟机栈里的局部变量、静态变量、常量等)为起点延伸连接、那么可以确定该对象是一个没有被任何对象引用的对象,从而可以被回收

回收的方式有哪些?

回收的方式可以分为标记-清除算法、标记-整理算法、复制算法

标记-清除把存活的对象标记,即是被引用的对象,未被标记的对象即没有被引用,则直接回收,缺点是直接清除可能会让内存区的空间造成不连续的局面,产生很多内存碎片,后续分配大对象时可能找不到连续空间。

标记-整理:和标记-清楚类似,只是在标记存活的对象之后,会把存活的对象先移向一侧,让未被标记和空闲空间在另一侧,然后清理边界外的内存,这一就可以合理分配空间,但移动对象会有性能开销。

复制算法:在一块内存区分成两个小的内存块,一块存放需要复制的存活内存,另一块则为空,在回收时期,把存活的对象放入空内存,然后清理内存,缺点是不管是否在gc时期都需要留出一半内存来为gc做准备,会浪费一半内存

实际中,JVM会分代使用上述算法,因为对象的生命周期不同,在新生代对象中存活率较低老年代(存活久的对象)存活率高新生代一般用复制算法,与理论复制算法不用,实际中会把内存分为Eden区和两个Survivor区,内存占比8:1:1,新对象都先进Eden区,在Eden区满了之后会触发Minor GC 然后把存活的对象放入一个Survivor区,然后清空eden区之后下一次就使用Eden区和另一个空的Survivor区,多次存活后移到老年代。老年代 “标记 - 清除” 或 “标记 - 整理”,因为对象存活率高,复制成本太高。

不用担心Eden区放入Survivor区会放不下,因为Eden区存活的对象都比较少大部分都是未被标记的对象,内存的1/10完全够用

回收器有哪些?

Serial GC:单线程回收,简单且但效率低,适合小型应用。

Pararllel GC:多线程回收,单位时间内处理的任务多,吞吐量高

CMS:追求低延迟回收,回收时大部分线程和用户线程并发执行,减少停顿时间,但会占用更多cpu

G1:把内存分成多个区域,优先回收占用最多的区域,保持各区域平衡

新出的ZGC、Shenandoah追求微秒级停顿适合高并发场景使用

总结:gc的核心是自动管理内存,通过可达性分析算法来确定垃圾对象,通过不同的回收方式和回收器来帮助回收垃圾对象所占用的资源,让程序在正常执行的清空下,高效清理内存空间,减少堆用户线程的影响

垃圾回收算法有哪些?

标记-清除算法:标记-清除算法分为“标记”和“清除”两个阶段,首先通过可达性分析,标记出所有需要回收的对象,然后统一回收所有被标记的对象。标记-清除算法有两个缺陷,一个是效率问题,标记和清除的过程效率都不高,另外一个就是,清除结束后会造成大量的碎片空间。有可能会造成在申请大块内存的时候因为没有足够的连续空间导致再次 GC。

复制算法:为了解决碎片空间的问题,出现了“复制算法”。复制算法的原理是,将内存分成两块,每次申请内存时都使用其中的一块,当内存不够时,将这一块内存中所有存活的复制到另一块上。然后将然后再把已使用的内存整个清理掉。复制算法解决了空间碎片的问题。但是也带来了新的问题。因为每次在申请内存时,都只能使用一半的内存空间。内存利用率严重不足。

标记-整理算法:复制算法在 GC 之后存活对象较少的情况下效率比较高,但如果存活对象比较多时,会执行较多的复制操作,效率就会下降。而老年代的对象在 GC 之后的存活率就比较高,所以就有人提出了“标记-整理算法”。标记-整理算法的“标记”过程与“标记-清除算法”的标记过程一致,但标记之后不会直接清理。而是将所有存活对象都移动到内存的一端。移动结束后直接清理掉剩余部分。

分代回收算法:分代收集是将内存划分成了新生代和老年代。分配的依据是对象的生存周期,或者说经历过的 GC 次数。对象创建时,一般在新生代申请内存,当经历一次 GC 之后如果对还存活,那么对象的年龄 +1。当年龄超过一定值(默认是 15,可以通过参数 -XX:MaxTenuringThreshold 来设定)后,如果对象还存活,那么该对象会进入老年代。

总结

到此这篇关于Java GC面试必问三件套有哪些的文章就介绍到这了,更多相关Java GC面试必问内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • MapReduce中ArrayWritable 使用指南

    MapReduce中ArrayWritable 使用指南

    MapReduce是一种编程模型,用于大规模数据集的并行运算。概念"Map(映射)"和"Reduce(归约)"和他们的主要思想,都是从函数式编程语言里借来的,还有从矢量编程语言里借来的特性。他极大地方便了编程人员在不会分布式并行编程的情况下,将自己的程序运行在分布式系统上。
    2014-08-08
  • 如何基于SpringBoot实现人脸识别功能

    如何基于SpringBoot实现人脸识别功能

    人工智能时代的到来,相信大家已耳濡目染,虹软免费,离线开放的人脸识别SDK,正推动着全行业进入刷脸时代,下面这篇文章主要给大家介绍了关于如何基于SpringBoot实现人脸识别功能的相关资料,需要的朋友可以参考下
    2022-05-05
  • java 导入Excel思路及代码示例

    java 导入Excel思路及代码示例

    这篇文章主要介绍了java 导入Excel思路及代码示例,简要分析了设计思路,然后分享了实例代码,具有一定参考价值,需要的朋友可以了解下。
    2017-11-11
  • 一篇文章带你搞定JAVA Maven

    一篇文章带你搞定JAVA Maven

    Maven是每个Java程序都会遇到的包管理工具,今天整理一下Maven的相关知识,从青铜到王者,一文全了解,我们开始吧,希望对你有所帮助
    2021-07-07
  • java中求高精度除法,要求保留N位小数

    java中求高精度除法,要求保留N位小数

    这篇文章主要介绍了java中求高精度除法,要求保留N位小数的实现,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-08-08
  • mybatis插入与批量插入返回ID的原理详解

    mybatis插入与批量插入返回ID的原理详解

    这篇文章主要给大家介绍了关于mybatis插入与批量插入返回ID的原理的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用mybatis具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-07-07
  • Java并发编程如何降低锁粒度并实现性能优化

    Java并发编程如何降低锁粒度并实现性能优化

    这篇文章主要介绍了Java并发编程如何降低锁粒度并实现性能优化,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-08-08
  • Mybatis两种不同批量插入方式的区别

    Mybatis两种不同批量插入方式的区别

    随着业务需要,有时我们需要将数据批量添加到数据库,mybatis提供了将list集合循环添加到数据库的方法,这篇文章主要给大家介绍了关于Mybatis两种不同批量插入方式的区别,需要的朋友可以参考下
    2021-09-09
  • java实现动态上传多个文件并解决文件重名问题

    java实现动态上传多个文件并解决文件重名问题

    这篇文章主要为大家详细介绍了java实现动态上传多个文件,并解决文件重名问题的方法,感兴趣的小伙伴们可以参考一下
    2016-03-03
  • java实例方法被覆盖,静态方法被隐藏Explain(详解)

    java实例方法被覆盖,静态方法被隐藏Explain(详解)

    下面小编就为大家带来一篇java实例方法被覆盖,静态方法被隐藏Explain(详解)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-05-05

最新评论