当前位置: 首页 > news >正文

java面试-GC垃圾回收机制

原理:

GC是垃圾收集的意思(Garbage Collection),Java提供的GC功能可以自动监测对象是否超过作用域从而达到自动回收内存的目的。

简而言之,GC是将java的无用的堆对象进行清理,释放内存,以免发生内存泄露。

问题一:为什么需要垃圾回收?

答:如果不进行垃圾回收,内存迟早都会被消耗空,因为我们在不断的分配内存空间而不进行回收。除非内存无限大,我们可以任性的分配而不回收,但是事实并非如此。所以,垃圾回收是必须的。

问题二:常见的垃圾回收算法有哪些?

答:

1、标记-清除算法 (老年代GC采用的算法)

分为两个阶段:标记阶段清除阶段

标记阶段:首先标记出所有需要回收的对象。

清除阶段:统一回收所有被标记的对象。

缺点:标记和清除过程效率都不高会产生大量不连续的内存碎片,导致无法给大对象分配内存。 

这种算法的不足主要体现在效率和空间,从效率的角度讲,标记和清除两个过程的效率都不高;从空间的角度讲,标记清除后会产生大量不连续的内存碎片, 内存碎片太多可能会导致以后程序运行过程中在需要分配较大对象时,无法找到足够的连续内存而不得不提前触发一次垃圾收集动作。

2、复制算法 (新生代GC采用的算法)

分为两个阶段:标记阶段复制阶段

标记阶段:首先需要先标记出存活的对象。

复制阶段:把存活的对象都复制到一块新的空内存里去,最后将原来的内存空间清空。

复制算法是为了解决效率问题而出现的,它将可用的内存分为两块,每次只用其中一块,当这一块内存用完了,就将还存活着的对象复制到另外一块上面,然后再把已经使用过的内存空间一次性清理掉

缺点:内存缩小为了原来的一半,在对象存活率较高的场景下要进行大量的复制操作,效率很低。

 

3、标记-整理算法

分为三个阶段:标记阶段整理阶段清除阶段

标记阶段:首先需要先标记出存活的对象。

整理阶段:将所有的存活对象压缩到内存的一端。

清除阶段:把存活边界外的内存空间都清除一遍。

4、分代收集算法:

存活率低:少量对象存活,适合复制算法:在新生代中,每次GC时都发现有大批对象死去,只有少量存活(新生代中98%的对象都是“朝生夕死”),那就选用复制算法,只需要付出少量存活对象的复制成本就可以完成GC。

存活率高:大量对象存活,适合用标记-清理标记-整理算法:在老年代中,因为对象存活率高、没有额外空间对他进行分配担保,就必须使用“标记-清理”/“标记-整理”算法进行GC。

 现代商用虚拟机基本都采用分代收集算法来进行垃圾回收。这种算法没什么特别的,无非是上面内容的结合罢了,根据对象的生命周期的不同将内存划分为几块,然后根据各块的特点采用最适当的收集算法。大批对象死去、少量对象存活的(新生代),使用复制算法,复制成本低;对象存活率高、没有额外空间进行分配担保的(老年代),采用标记-清理算法或者标记-整理算法

问题三:介绍一下新生代、老年代、永久代和各种GC

答: 

JVM 中的堆,一般分为三大部分:新生代、老年代、永久代

1. 新生代

主要是用来存放新生的对象,新生代通常存活时间较短。一般占据堆的 1/3 空间。由于频繁创建对象,所以新生代会频繁触发 MinorGC(也叫新生代GC) 进行垃圾回收。

MinorGC:采用复制算法。(问题二有介绍复制算法)

新生代分为 Eden 区ServivorFromServivorTo 三个区。

  • Eden 区:Java 新对象的出生地(如果新创建的对象占用内存很大,则直接分配到老年代)。当 Eden 区内存不够的时候就会触发 MinorGC,对新生代区进行一次垃圾回收。
  • ServivorTo:保留了一次 MinorGC 过程中的幸存者。
  • ServivorFrom:上一次 GC 的幸存者,作为这一次 GC 的被扫描者。

当 JVM 无法为新建对象分配内存空间的时候 (Eden 满了),Minor GC 被触发。因此新生代空间占用率越高,Minor GC 越频繁。

可以看出触发新生代GC的条件是Eden 满了

2. 老年代

老年代的对象比较稳定,对象存活的时间比较长。所以 MajorGC 不会频繁执行。在进行 MajorGC(也叫老年代GC) 前一般都先进行了一次 MinorGC新生代GC),使得有新生代的对象晋身入老年代,导致空间不够用时才触发。当无法找到足够大的连续空间分配给新创建的较大对象时也会提前触发一次 MajorGC 进行垃圾回收腾出空间。

MajorGC: 采用标记—清除算法 (问题二有介绍标记—清除算法)  * 有的地方等同于Full GC,有的地方单单指老年代的GC。

3. 永久代

指内存的永久保存区域,主要存放 Class 和 Meta(元数据)的信息

Class 在被加载的时候被放入永久区域。它和和存放实例的区域不同,GC 不会在主程序运行期对永久区域进行清理。所以这也导致了永久代的区域会随着加载的 Class 的增多而胀满,最终抛出 OOM 异常。

在 Java8 中,永久代已经被移除,被一个称为 “元数据区”(元空间)的区域所取代。

元空间的本质和永久代类似,都是对 JVM 规范中方法区的实现。不过元空间与永久代之间最大的区别在于:元空间并不在虚拟机中,而是使用本地内存。因此,默认情况下,元空间的大小仅受本地内存限制。类的元数据放入 native memory, 字符串池和类的静态变量放入 java 堆中. 这样可以加载多少类的元数据就不再由 MaxPermSize 控制, 而由系统的实际可用空间来控。

问题四:堆是怎么构成的?

答:堆 = 新生代 + 老年代

其中,新生代 ( Young ) 被细分为 Eden 两个 Survivor 区域,这两个 Survivor 区域分别被命名为 From Survivor To Survivor ,以示区分。
默认的,Edem : from : to = 8 : 1 : 1 。可以通过参数 –XX:SurvivorRatio 来设定 ,即:
Survivor区和Eden区的比值

持续更新中....

参考博客:

Java内存垃圾回收(GC)原理_Zhang.Voi的博客-CSDN博客_java内存回收机制原理

https://www.jianshu.com/p/3d61a0e0e006

GC触发条件,堆的构成_水滴石穿007的博客-CSDN博客_gc触发条件

相关文章:

  • TOREX | 如何延长设备的电池寿命?——充电IC
  • 电路方案分析(十一)低电平(5uA)V-I转化器
  • 【Hadoop生态圈】8.Flink入门教程
  • 代码整洁之道,评审问题分享记录
  • 【调研】详解Transformer结构——Attention Is All You Need
  • Linux基础组件之消息协议设计概述
  • [ vulhub漏洞复现篇 ] struts2远程代码执行漏洞 S2-005 (CVE-2010-1870)
  • 微服务Spring Boot 整合 Redis 分布式锁 Redission 实现优惠卷秒杀 一人一单
  • java毕业设计医护人员排班系统Mybatis+系统+数据库+调试部署
  • 分库分表实战之从根上带你吃透MySQL的索引
  • 学习大数据环境搭建
  • STM32——SD卡实验(SDIO方式)
  • JavaWeb(部分)
  • 还在盲目内卷?腾讯强推Spring Security 速成笔记,认证授权一键拿下
  • 【Vue】Vue中的侦听器watch
  • “寒冬”下的金三银四跳槽季来了,帮你客观分析一下局面
  • 「前端」从UglifyJSPlugin强制开启css压缩探究webpack插件运行机制
  • 【Under-the-hood-ReactJS-Part0】React源码解读
  • axios请求、和返回数据拦截,统一请求报错提示_012
  • E-HPC支持多队列管理和自动伸缩
  • happypack两次报错的问题
  • java多线程
  • macOS 中 shell 创建文件夹及文件并 VS Code 打开
  • PhantomJS 安装
  • quasar-framework cnodejs社区
  • UEditor初始化失败(实例已存在,但视图未渲染出来,单页化)
  • Vue学习第二天
  • 基于阿里云移动推送的移动应用推送模式最佳实践
  • 利用DataURL技术在网页上显示图片
  • 学习笔记:对象,原型和继承(1)
  • Spring第一个helloWorld
  • ​Java并发新构件之Exchanger
  • ​ssh-keyscan命令--Linux命令应用大词典729个命令解读
  • ​TypeScript都不会用,也敢说会前端?
  • (145)光线追踪距离场柔和阴影
  • (笔试题)分解质因式
  • (二)PySpark3:SparkSQL编程
  • (附源码)ssm高校志愿者服务系统 毕业设计 011648
  • (附源码)ssm跨平台教学系统 毕业设计 280843
  • (完整代码)R语言中利用SVM-RFE机器学习算法筛选关键因子
  • (原創) 是否该学PetShop将Model和BLL分开? (.NET) (N-Tier) (PetShop) (OO)
  • (转)h264中avc和flv数据的解析
  • (转)MVC3 类型“System.Web.Mvc.ModelClientValidationRule”同时存在
  • (转)程序员技术练级攻略
  • (转载)利用webkit抓取动态网页和链接
  • (轉貼)《OOD启思录》:61条面向对象设计的经验原则 (OO)
  • . NET自动找可写目录
  • .chm格式文件如何阅读
  • .NET 4.0网络开发入门之旅-- 我在“网” 中央(下)
  • .NET 6 在已知拓扑路径的情况下使用 Dijkstra,A*算法搜索最短路径
  • .NET Compact Framework 多线程环境下的UI异步刷新
  • .NET Core引入性能分析引导优化
  • .net 调用php,php 调用.net com组件 --
  • .net 托管代码与非托管代码
  • .Net调用Java编写的WebServices返回值为Null的解决方法(SoapUI工具测试有返回值)