【Java虚拟机】垃圾回收机制

什么是Java里的垃圾回收机制?如何触发垃圾回收?

垃圾回收机制是一种内存管理机制,通过回收哪些不再被引用的对象,从而释放他们所占用的内存。避免内存泄漏和内存溢出

触发方式:

  • 手动触发:通过调用system.gc()或者Runtime.getRuntime.gc()来建议JVM进行垃圾回收,但是不会立即触发。
  • 当内存不足时会自动触发
  • 可以通过手动调节JVM的参数来进行触发
  • 当创建对象的数量或者使用的内存达到阈值时触发

判断垃圾的方式有哪些

  • 引用计数法:它的原理是在创建对象时为其分配一个引用计数器,当该对象被引用时,计数器+1,当不再被引用时计数器-1.当计数器为0时,说明该对象不再被引用,可以被清除。但是该算法有个弊端:如果两个对象互相引用但是没有其他对象再进行引用时,这两个对象无法被清除。
  • 可达性分析算法:它的原理是:从GC Roots出发,获取其所引用的对象,以及该对象引用的对象。如果一个对象没有任何一个引用链可以到达GC Roots说明该对象可以被垃圾回收。

垃圾回收算法有哪些

  • 标记-清除算法:该算法有两个步骤,标记和清除。首先根据可达性分析,标记那些不再被引用的对象。然后将其清除。该算法有两个缺点:1.效率不高:标记和清除两个步骤的效率都不高。2.容易产生内存碎片。
  • 复制算法:它的原理是将内存划分为两个区域,当垃圾回收时,将存活的对象转移到另一个区域,再清除该区域。该算法的内存利用率不高,因为每次只使用一半的内存。
  • 标记-整理算法:分为两步,第一步标记与标记-清除法的标记操作类似。第二步:将仍然存活的对象转移到内存的另一端。再清除剩余内存。该算法不会产生内存碎片。
  • 分代回收算法:通过将内存划分为新生代和老年代,当创建对象时先分配到新生代,当出发GC时,年龄+1,当年龄达到阈值时,将其转移到老年代。

minor GC,major GC,full GC的区别以及触发条件

  • minor GC:作用范围:新生代,包括伊甸区和幸存者区。触发条件:当伊甸区内存不足时会触发minor GC将伊甸区和其中一个幸存者区仍然存活的对象转移到另一个幸存者区和老年代。特点:触发的频率比较高,停顿时间比较短。
  • major GC:作用范围:老年代,但不仅仅只回收老年代。触发条件:当老年代空间不足,或者检测到新生代晋升为老年代的速度过快时。特点:触发的频率较低,但是时间比较长。
  • full GC: 作用范围:整个堆内存,包括元空间。触发条件:1.当永久代或元空间内存不足时 。2.当Minor GC时新生代对象无法全部存放到老年代时,或者老年代空间不足以存放存活对象时。3.当手动调用system.gc()或Runtime.getRuntime.gc()时。特点:full GC是最昂贵的垃圾回收,因为他会停止所有线程去遍历堆内存寻找不再被使用的对象。

垃圾回收器CMS和G1的区别

  • 1.作用范围不同:CMS作用于老年代,可以配合新生代收集器serial和ParNew使用。G1收集器作用与新生代和老年代。
  • 2.STW不同:CMS收集器旨在获取最短停顿时间,而G1收集器可以预测垃圾停顿时间。
  • 3.内存碎片:CMS收集器采用的是标记-清除算法,会产生内存碎片。而G1收集器采用的是标记-整理法,不会产生内存碎片。
  • 4.执行步骤不同:CMS的步骤为:初始化标记,并发标记,重新标记,并发清除。G1收集器的步骤为:初始化标记,并发标记,最终标记,筛选回收。
  • 5.CMS会产生浮动垃圾:CMS的第四阶段并发清除是垃圾回收线程和用户使用线程并发进行的,会产生浮动垃圾,CMS会为其预留一部分空间。G1收集器不会产生浮动垃圾,它的第四阶段是所有垃圾回收线程并行执行的,不涉及浮动垃圾的清除。

什么情况下使用CMS,什么情况下使用G1?

  • CMS:1.当对时间比较敏感时可以使用CMS。2.当针对老年代进行垃圾回收时。3。由于会产生内存碎片,所以需要定期触发full GC 来压缩空间的。
  • G1:1.大堆内存,2.对内存碎片比较敏感。3.性能均衡:G1收集器同时拥有较低的停顿时间,又有较大的吞吐量。

G1 收集器的特色是什么

G1收集器最大的特点是:采用了分区的概念,淡化了分代的概念。

相较于CMS收集器,G1的特点:

  • 没有内存碎片的产生
  • 可以提前设置预期停顿时间,避免应用雪崩的现象
  • G1收集器更能有效利用多核CPU的硬件优势

GC只会对堆进行GC吗

不是,还会对方法区进行垃圾回收。

相关推荐
2601_9491465333 分钟前
C语言语音通知接口接入教程:如何使用C语言直接调用语音预警API
c语言·开发语言
曹牧38 分钟前
Spring Boot:如何测试Java Controller中的POST请求?
java·开发语言
KYGALYX44 分钟前
服务异步通信
开发语言·后端·微服务·ruby
zmzb01031 小时前
C++课后习题训练记录Day98
开发语言·c++
爬山算法1 小时前
Hibernate(90)如何在故障注入测试中使用Hibernate?
java·后端·hibernate
kfyty7252 小时前
集成 spring-ai 2.x 实践中遇到的一些问题及解决方案
java·人工智能·spring-ai
猫头虎2 小时前
如何排查并解决项目启动时报错Error encountered while processing: java.io.IOException: closed 的问题
java·开发语言·jvm·spring boot·python·开源·maven
李少兄2 小时前
在 IntelliJ IDEA 中修改 Git 远程仓库地址
java·git·intellij-idea
YUJIANYUE2 小时前
PHP纹路验证码
开发语言·php
忆~遂愿2 小时前
ops-cv 算子库深度解析:面向视觉任务的硬件优化与数据布局(NCHW/NHWC)策略
java·大数据·linux·人工智能