JVM垃圾回收机制

news/2024/4/27 3:04:18

文章目录

  • 1.标记清除法(标记不能清除的,清除其余的)
  • 2.标记整理法
  • 3.标记复制法(标记不能清除的)
  • 分代回收思想:
  • 三色标记法
  • 漏标问题
  • 垃圾回收规模:
  • 什么是STW?
  • 并发标记
  • 常见的垃圾回收器的实现
    • Parallel GC
    • ConcurrentMarkSweep GC
    • G1 GC

java垃圾回收的区域是虚拟机堆。

1.标记清除法(标记不能清除的,清除其余的)

在这里插入图片描述

沿着GC Root对象(一定不会被清除的对象)的引用链往下找,对引用链上的对象都加上标记,清除那些没有被标记的对象。
一个对象不能被清除,那他的引用链上的对象必须也不能清除,不能说我想用的时候拿到的是null,那这样就没法用了。

缺点:清除后得到的内存不连续,内存碎片用处不大。
应用场景:无,目前已经废弃。

2.标记整理法

在这里插入图片描述
标记清除法的基础上增加一步整理动作,把不连续的内存变为连续的。
缺点:性能低,因为多了整理动作。
应用场景:堆内存老年代的垃圾回收机制。
因为老年代存活对象多,垃圾对象少,使用标记复制法要复制的对象太多了而且老年代占用内存多,如果使用标记复制法需要准备更多的另一块内存空间。

3.标记复制法(标记不能清除的)

标记不能被清除的对象,然后把这些对象直接移动到另一个区域,这片区域直接作废,另一片区域也不再需要进行整理。
在这里插入图片描述
缺点:占用一份额外的内存。
应用场景:用于堆内存的新生代的垃圾回收机制。
因为新生代能存活对象比较少,垃圾对象多。只需要简单复制很少的一部分对象,就能完成工作。而且新生代占用的内存少,所需另一块内存空间也少。

新生代中eden区复制到survicor区的垃圾回收示例
一个对象首先被分配到Eden区,当Eden区满时,会触发一次Minor GC。把Eden区中存活的对象复制到其中一个Survivor区(),同时清理掉不再被引用的对象。

新生代的from区复制到to区的垃圾回收示例:

  1. 将整个内存分成两个大小相等的区域,from 和 to,其中 to 总是处于空闲,from 存储新创建的对象
  2. 标记阶段与前面的算法类似
  3. 在找出存活对象后,会将它们从 from 复制到 to 区域,复制的过程中自然完成了碎片整理
  4. 复制完成后,交换 from 和 to 的位置即可

分代回收思想:

我们将虚拟机堆分为新生代和老年代,新生代和老年代特性不同,所以我们用不同的垃圾回收策略。

三色标记法

前面我们说到对引用链上的对象添加标记,三色标记法就是其中一种实现。
即用三种颜色记录对象的标记状态

  • 黑色 – 已标记(沿着跟对象的引用链找到这个对象了,并且这个对象中引用的对象也标记完成了)
  • 灰色 – 标记中(沿着跟对象的引用链找到这个对象了,但是这个对象中引用的其他对象还在标记中)
  • 白色 – 还未标记

1.起始的三个对象还未处理完成,用灰色表示
在这里插入图片描述
2.该对象的引用已经处理完成,用黑色表示,黑色对象引用的对象变为灰色
在这里插入图片描述
3.依次类推
在这里插入图片描述
4. 沿着引用链都标记了一遍
在这里插入图片描述
5.最后为标记的白色对象,即为垃圾
在这里插入图片描述

漏标问题

先进的垃圾回收器都是支持并发标记的,即标记的线程和用户线程同时工作,这就会带来一个问题,如果在标记的过程中,用户修改了已经被标为黑色的对象 的引用对象,这个新对象就会一直是白色,被标为垃圾对象,最后被垃圾回收掉,导致引用为null无法正常工作。

解决办法:
1.增量更新法(Incremental Update)
思路是拦截每次赋值动作,只要赋值发生,被赋值的对象就会被记录下来不做处理,等标记完成后,把用户线程停止一段时间然后把被记录下来的对象变为灰色再标记一遍。
2.原始快照法(Snapshot At The Beginning)G1(GC的具体实现) 垃圾回收器采用
思路也是拦截每次赋值动作,不过记录的对象不同,然后在重新标记阶段对这些被标记的对象二次处理.
新加对象会被记录
被删除引用关系的对象也被记录

垃圾回收规模:

  • Minor GC 发生在新生代的垃圾回收,暂停时间短

  • Mixed GC 新生代 + 老年代部分区域的垃圾回收,G1 垃圾回收器特有

  • Full GC 新生代 + 老年代完整垃圾回收,暂停时间长,应尽力避免

什么是STW?

STW: Stop-The-World,是在垃圾回收算法执⾏过程当中,需要将JVM内存冻结的⼀种状态。在STW状态下,除了垃圾回收线程外JAVA的所有线程会停止,native⽅法可以执⾏,但是,不能与JVM交互。GC各种算法优化的重点,就是减少STW。

并发标记

在垃圾回收(Garbage Collection)中,并发标记是指在进行垃圾回收时,程序的执行和垃圾回收的标记过程可以同时进行,即并发执行。

常见的垃圾回收器的实现

Parallel GC

Paraller-并行的
Parallel GC(Parallel Collector):也称为吞吐量优先收集器,使用多个垃圾回收线程并行进行垃圾回收,适用于需要高吞吐量的应用程序。

  • eden 内存不足发生 Minor GC,需要暂停用户线程STW
  • old 内存不足发生 Full GC,需要暂停用户线程STW
  • 注重吞吐量

ConcurrentMarkSweep GC

CMS收集器(Concurrent Mark-Sweep Collector):是一种并发垃圾回收器,旨在减少垃圾回收造成的停顿时间。

  • 它是工作在 old 老年代,支持并发标记的一款回收器,采用并发标记清除算法(所以已经废弃)

    • 并发标记时不需暂停用户线程
    • 重新标记时仍需暂停用户线程
  • 如果并发失败(即回收速度赶不上创建新对象速度),会触发 Full GC

  • **注重响应时间

G1 GC

JDK9开始作为默认垃圾回收器.G1垃圾回收器兼顾吞吐量与响应时间
原理:把整个虚拟机堆划分为多个大小相等的区域,每个区域都可以充当eden区,survivor区,old区,humongous区域,其中 humongous 专为大对象准备。

  • 分成三个阶段:新生代回收、并发标记与混合收集
  • 如果并发失败(即回收速度赶不上创建新对象速度),会触发 Full GC

新生代中的回收

  1. 初始时,所有区域都处于空闲状态

在这里插入图片描述

  1. 创建了一些对象,挑出一些空闲区域作为伊甸园区存储这些对象
    在这里插入图片描述

  2. 当伊甸园需要垃圾回收时,挑出一个空闲区域作为幸存区,用复制算法复制存活对象,需要暂停用户线程
    在这里插入图片描述

  3. 复制完成,将之前的伊甸园内存释放

在这里插入图片描述

  1. 创建了一些对象,再次挑出一些空闲区域作为伊甸园区存储这些对象,随着时间流逝,伊甸园的内存又有不足

在这里插入图片描述

  1. 伊甸园以及之前幸存区中的存活对象,采用复制算法,复制到新的幸存区,其中幸存区中较老对象会晋升至老年代

在这里插入图片描述

  1. 释放伊甸园以及之前幸存区的内存

在这里插入图片描述

并发标记与混合收集

  1. 当老年代占用内存超过阈值(老年代内存占比达到堆内存的45%以上)后,触发并发标记(标记的同时不暂停用户线程)
    在这里插入图片描述

  2. 并发标记之后,会有重新标记阶段解决漏标问题,此时需要暂停用户线程。这些都完成后就知道了老年代有哪些存活对象。

    随后进入混合收集阶段。此时不会对所有老年代区域进行回收,而是根据预期暂停时间优先释放对象少,能释放更多内存)的区域(这也是 Gabage First 名称的由来)。

在这里插入图片描述

  1. 混合收集阶段中,参与复制的有 eden、survivor、old,下图显示了伊甸园和幸存区的存活对象复制

在这里插入图片描述

  1. 老年代存活对象少的区域复制到新的老年代区域,幸存区中达到晋升条件的幸存对象晋升到新的老年代

在这里插入图片描述

  1. 复制完成,内存得到释放。进入下一轮的新生代回收、并发标记、混合收集

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.cpky.cn/p/11154.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

151 shell编程,正则表达式,在C语言中如何使用正则表达式

零,坑点记录:bash 和 dash 的区别,导致的坑点 查看当前用的shell 是啥,用的是/bin/bash hunandedehunandede-virtual-machine:~$ echo $SHELL /bin/bash 当shell 脚本运行的时候(后面会学到方法,这里是最…

耳目一新的滑块版登录注册界面~

又到了毕业季,大家做毕设的时候总会参考已有的案例,不过大多产品的样式非常单一雷同。本帖博主给大家分享一个比较别树一帜的登录界面,如下: 如果没有账号,点击“去注册”,则会产生如下的效果: …

倍压器电路原理及仿真

倍压器是利用二极管单向导通的特性和电容两端电压不能突变且可以存储能量的特性,使得能量逐步往后级输送,同时线路上的电压也逐渐升高。因此,它可以实现将较低的交流电压转换成一个较高的直流电压。根据倍压的原理,有二倍压、三倍…

绝地求生:PUBG七周年:荣都人机进阶打法!

再给大家写一点攻略,荣都又上线了,但是我发现很多朋友打个人机都不利索。 原因在于荣都的两个人机点NPC太多,并且还是三级兑换点跳人很多,一旦打起来情况非常混乱,最近和朋友总结一套人机打法。 食王府 食王府一定要从…

AQS源码分析

前言 AbstractQueuedSynchronizer是抽象同步队列,其是实现同步机器的基础组件,并发包中的锁的底层就是使用AQS实现的。AQS中 维护了一个volatile int state(代表共享资源)和一个FIFO线程等待队列(多线程争用资源被阻塞…

01、Lua 入门教程

Lua 入门教程 Lua是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。 Lua是巴西里约热内卢天主教大学(Pontifical Catholic University of…