垃圾收集器面试总结(二)

news2024/11/14 20:35:33

G1 收集器

G1 (Garbage-First) 是一款面向服务器的垃圾收集器,主要针对配备多颗处理器及大容量内存的机器。 以极高概率满足 GC 停顿时间要求的同时,还具备高吞吐量性能特征。

被视为 JDK1.7 中 HotSpot 虚拟机的一个重要进化特征。它具备以下特点:

  • 并行与并发: G1能充分利用多CPU、多核环境下的硬件优势,使用多个CPU(CPU或者CPU核心)来缩短Stop-The-World停顿的时间,部分其他收集器原本需要停顿Java线程执行的GC动作,G1收集器仍然可以通过并发的方式让Java程序继续执行。

  • 分代收集: 与其他收集器一样,分代概念在G1中依然得以保留。虽然G1可以不需要其他收集器配合就能独立管理整个GC堆,但它能够采用不同的方式去处理新创建的对象和已经存活了一段时间、熬过多次GC的旧对象以获取更好的收集效果。

  • 空间整合: 与CMS的“标记—清理”算法不同,G1从整体来看是基于“标记—整理”算法实现的收集器,从局部(两个Region之间)上来看是基于“标记—复制”算法实现的,但无论如何,这两种算法都意味着G1运作期间不会产生内存空间碎片,收集后能提供规整的可用内存。这种特性有利于程序长时间运行,分配大对象时不会因为无法找到连续内存空间而提前触发下一次GC。

  • 可预测的停顿: 这是G1相对于CMS的另一大优势,降低停顿时间是G1和CMS共同的关注点,但G1除了追求低停顿外,还能建立可预测的停顿时间模型,能让使用者明确指定在一个长度为M毫秒的时间片段内,消耗在垃圾收集上的时间不得超过N毫秒,这几乎已经是实时Java(RTSJ)的垃圾收集器的特征了。

在G1之前的其他收集器进行收集的范围都是整个新生代或者老年代,而G1不再是这样。使用G1收集器时,Java堆的内存布局就与其他收集器有很大差别,它将整个Java堆划分为多个大小相等的独立区域(Region),虽然还保留有新生代和老年代的概念,但新生代和老年代不再是物理隔离的了,它们都是一部分Region(不需要连续)的集合。

在这里插入图片描述

在G1中,还有一种特殊的区域,叫Humongous区域。 如果一个对象占用的空间超过了分区容量50%以上,G1收集器就认为这是一个巨型对象。这些巨型对象,默认直接会被分配在年老代,但是如果它是一个短期存在的巨型对象,就会对垃圾收集器造成负面影响。为了解决这个问题,G1划分了一个Humongous区,它用来专门存放巨型对象。如果一个H区装不下一个巨型对象,那么G1会寻找连续的H分区来存储。为了能找到连续的H区,有时候不得不启动Full GC。

G1收集器之所以能建立可预测的停顿时间模型,是因为它可以有计划地避免在整个Java堆中进行全区域的垃圾收集。G1跟踪各个Region里面的垃圾堆积的价值大小(回收所获得的空间大小以及回收所需时间的经验值),在后台维护一个优先列表,每次根据允许的收集时间,优先回收价值最大的Region(这也就是Garbage-First名称的来由)。这种使用Region划分内存空间以及有优先级的区域回收方式,保证了G1收集器在有限的时间内可以获取尽可能高的收集效率。

一个对象分配在某个Region中,它并非只能被本Region中的其他对象引用,而是可以与整个Java堆任意的对象发生引用关系。那在做可达性判定确定对象是否存活的时候,岂不是还得扫描整个Java堆才能保证准确性?这个问题其实并非在G1中才有,只是在G1中更加突出而已。在以前的分代收集中,新生代的规模一般都比老年代要小许多,新生代的收集也比老年代要频繁许多,那回收新生代中的对象时也面临相同的问题,如果回收新生代时也不得不同时扫描老年代的话,那么Minor GC的效率可能下降不少。

在其他垃圾收集器中,通过CardTable来维护老年代对年轻代的引用,CardTable可以说是Remembered Set(RS)的一种特殊实现,是Card的集合。Card是一块2的幂字节大小的内存区域,例如HotSpot用512字节,里面可能包含多个对象。CardTable要记录的是从它覆盖的范围出发指向别的范围的指针。以分代式GC的CardTable为例,要记录老年代指向年轻代的跨代指针,被标记的Card是老年代范围内的。当进进行年轻代的垃圾收集时,只需要扫描年轻代和老年代的CardTable即可保证不对全堆扫描也不会有遗漏。CardTable通常为字节数组,由Card的索引(即数组下标)来标识每个分区的空间地址。默认情况下,每个卡都未被引用。当一个地址空间被引用时,这个地址空间对应的数组索引的值被标记为”0″,即标记为dirty card。

在G1收集器中,也有和上面一样的CardTable。另外G1中每个Region还有一个与之对应的Remembered Set,虚拟机发现程序在对Reference类型的数据进行写操作时,会产生一个 Write Barrier暂时中断写操作,检查Reference引用的对象是否处于不同的Region之中,如果是,便通过CardTable把相关引用信息记录到被引用对象所属的Region的Remembered Set之中。当进行内存回收时,在GC根节点的枚举范围中加入Remembered Set即可保证不对全堆扫描也不会有遗漏。

在这里插入图片描述

G1收集器的垃圾收集分两种:Minor GC(Young GC)和 Mixed GC(Old GC)。

G1:Minor GC

Young GC大致可以分为5个阶段:

  • 根扫描: 静态和本地对象被扫描。
  • 更新RS: 处理dirty card队列更新RS。
  • 处理RS: 检测从年轻代指向年老代的对象。
  • 对象拷贝: 拷贝存活的对象到survivor/old区域。
  • 处理引用队列: 软引用,弱引用,虚引用处理。

G1:Mixed GC

Mixed GC大致可划分为全局并发标记(global concurrent marking)和拷贝存活对象(evacuation)两个大部分:

global concurrent marking是基于SATB形式的并发标记,包括以下4个阶段:初始标记(Initial Marking)、并发标记(Concurrent Marking)、最终标记(Final Marking)、清理(Clean Up)。

  • 初始标记(initial marking): 暂停阶段(会 STW)。扫描根集合,标记所有从根集合可直接到达的对象并将它们的字段压入扫描栈(marking stack)中等待后续扫描。G1使用外部的bitmap来记录mark信息,而不使用对象头的mark word里的mark bit。在分代式G1模式中,初始标记阶段借用young GC的暂停,因而没有额外的、单独的暂停阶段。

  • 并发标记(concurrent marking): 并发阶段(不会 STW)。不断从扫描栈取出引用递归扫描整个堆里的对象图。每扫描到一个对象就会对其标记,并将其字段压入扫描栈。重复扫描过程直到扫描栈清空。过程中还会扫描SATB write barrier所记录下的引用。

  • 最终标记(final marking,在实现中也叫remarking): 暂停阶段(会 STW)。在完成并发标记后,每个Java线程还会有一些剩下的SATB write barrier记录的引用尚未处理。这个阶段就负责把剩下的引用处理完。同时这个阶段也进行弱引用处理(reference processing)。 注意这个暂停与CMS的remark有一个本质上的区别,那就是这个暂停只需要扫描SATB buffer,而CMS的remark需要重新扫描mod-union table里的dirty card外加整个根集合,而此时整个young gen(不管对象死活)都会被当作根集合的一部分,因而CMS remark有可能会非常慢。

  • 清理(cleanup)阶段: 暂停阶段(会 STW)。清点和重置标记状态。这个阶段有点像mark-sweep中的sweep阶段,不过不是在堆上sweep实际对象,而是在marking bitmap里统计每个region被标记为活的对象有多少。这个阶段如果发现完全没有活对象的region就会将其整体回收到可分配region列表中。

Evacuation阶段是全暂停的。它负责把一部分region里的活对象拷贝到空region里去,然后回收原本的region的空间。

Evacuation阶段可以自由选择任意多个region来独立收集构成收集集合(collection set,简称CSet),靠per-region remembered set(简称RSet)实现。这是regional garbage collector的特征。

在选定CSet后,evacuation其实就跟ParallelScavenge的young GC的算法类似,采用并行copying(或者叫scavenging)算法把CSet里每个region里的活对象拷贝到新的region里,整个过程完全暂停。从这个意义上说,G1的evacuation跟传统的mark-compact算法的compaction完全不同:前者会自己从根集合遍历对象图来判定对象的生死,不需要依赖global concurrent marking的结果,有就用,没有拉倒;而后者则依赖于之前的mark阶段对对象生死的判定。

纯G1模式下,CSet的选定完全靠统计模型找处收益最高、开销不超过用户指定的上限的若干region。由于每个region都有RSet覆盖,要单独evacuate任意一个或多个region都没问题。

在这里插入图片描述

对象漏标

垃圾回收的并发标记阶段,gc线程和应用线程是并发执行的,所以一个对象被标记之后,应用线程可能篡改对象的引用关系,从而造成对象的漏标、误标,其实误标没什么关系,顶多造成浮动垃圾,在下次gc还是可以回收的,但是漏标的后果是致命的,把本应该存活的对象给回收了,从而影响的程序的正确性。

为了解决在并发标记过程中,存活对象漏标的情况,GC HandBook把对象分成三种颜色(三色标记):

  • 黑色:从GCRoots开始,已扫描过它全部引用的对象,标记为黑色;
  • 灰色:扫描过对象本身,还没完全扫描过它全部引用的对象,标记为灰色;
  • 白色:还没扫描过的对象,标记为白色。

所以,漏标的情况只会发生在白色对象中,且同时满足下面两个条件:

  • 有至少一个黑色对象在自己被标记之后指向了这个白色对象;
  • 所有的灰色对象在自己引用扫描完成之前删除了对白色对象的引用。

例如:

D对象引用E对象,E引用G,此时GC正好处于D已经变成黑色,E处于灰色;
G是白色的情况下,此时因为业务逻辑的变化,E不引用G了,D对象引用了G;
按照三色标记法看,黑色对象是已完成状态,不可能再去找子引用,所以G就不会变成灰色,这样就会造成白色对象此时正在被线程使用中,
但是无法被标记成灰色或者白色,造成一个正在被使用的对象被错误回收。

这两个条件,必须全满足,才会造成漏标问题。换言之,我们破坏任何一个条件。这个白色对象,就不会再被漏标,这样就产生了两个解决办法。

CMS采用的是增量更新

增量更新破坏的是第一个条件,我们在这个黑色对象增加了对白色对象的引用之后,将它的这个引用记录下来,在最后标记的时候,再以这个黑色对象为根,对它的引用进行重新扫描。
​可以简单理解为,当一个黑色对象增加了对白色对象的引用,那么这个黑色对象就被变灰。这样有一个缺点,就是会重新扫描这个黑色对象的所有引用,比较浪费时间。

G1采用的是原始快照(SATB)

原始快照破坏的是第二个条件,我们在这个灰色对象取消对白色对象的引用之前,将这个引用记录下来,在最后标记的时候,再以这个引用指向的白色对象为根,对它的引用进行扫描。

可以简单理解为,当一个灰色对象取消了对白色对象的引用,那么这个白色对象被变灰。

​这样做的缺点就是,这个白色对象有可能并没有黑色对象去引用它,但是它还是被变灰了,就会导致它和它的引用,本来应该被垃圾回收掉,但是此次GC存活了下来,就是所谓的浮动垃圾.其实这样是比较可以忍受的,只是让它多存活了一次GC而已,浪费一点点空间,但是会比增量更新更省时间.

SATB

SATB全称snapshot-at-the-beginning,由Taiichi Yuasa为增量式标记清除垃圾收集器开发的一个算法,主要应用于垃圾收集的并发标记阶段,解决了CMS垃圾收集器重新标记阶段长时间STW的潜在风险。Region包含了5个指针,分别是bottom、previous TAMS、next TAMS、top和end。

在这里插入图片描述
在这里插入图片描述

JVM运行模式

JVM(Java虚拟机)有两种运行模式:Client模式和Server模式。它们的主要区别在于优化策略和内存管理方式。

  1. Client模式
    Client模式主要是针对启动时间短,但运行时间比较短的Java应用程序(如小型GUI应用程序等),通过减少JVM启动时间来提高应用程序的性能。在Client模式下,JVM会使用较少的内存来运行,以及使用较少的线程来处理请求。这些优化措施可以提高应用程序的启动速度和响应速度。
    优点:启动速度快,占用内存少。
    缺点:在长时间运行的情况下,由于内存和线程的限制,可能会导致应用程序的性能和响应速度下降。

  2. Server模式
    Server模式主要是针对长时间运行的Java应用程序(如Web服务器、应用服务器等)进行优化,通过提高JVM的性能和响应速度来处理高并发的请求。在Server模式下,JVM会使用更多的内存来运行,以及使用更多的线程来处理请求。这些优化措施可以提高应用程序的性能和响应速度。
    优点:针对长时间运行的Java应用程序进行了优化,可以提高应用程序的性能和响应速度。
    缺点:启动时间较长,占用的内存较多。

  3. 区别

     内存管理:Client模式下使用较少的内存,而Server模式下使用更多的内存。
     
     线程管理:Client模式下使用较少的线程,而Server模式下使用更多的线程。
     
     优化策略:Client模式主要优化启动时间和响应速度,而Server模式主要优化性能和响应速度。
     
     启动时间:Client模式启动时间短,而Server模式启动时间较长。
    

总之,选择JVM运行模式需要根据具体的应用场景来确定。对于启动时间短、运行时间短的Java应用程序,可以选择Client模式;而对于长时间运行的Java应用程序,可以选择Server模式。

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

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

相关文章

chatgpt智能提效职场办公-ppt怎么转换成word文档

作者:虚坏叔叔 博客:https://xuhss.com 早餐店不会开到晚上,想吃的人早就来了!😄 将PPT转换成Word文档有多种方法,以下是其中的一种: 打开PPT文件,并选择“文件”选项卡中的“另存为…

光流法Optical Flow,Lucas-Kanade方法,CV中光流的约束分析

光流法Optical Flow,Lucas-Kanade方法,CV中光流的约束分析 Multiple View Geometry1. Optical Flow Estimation2. The Lucas-Kanade Method2.1 Brightness Constancy Assumption2.2 Constant motion in a neighborhood2.3 Compute the velocity vector2.…

19 calloc 和 realloc 虚拟内存分配的调试

前言 前面提到了 malloc 虚拟内存分配相关的内容 malloc 虚拟内存分配的调试(1) malloc 虚拟内存分配的调试(2) 这里提 calloc 和 realloc, 这两个函数 虽然没有 malloc 使用频率那么高 但是 还是有很大的知名度的, 本文这里 我们来看一下 calloc 此函数传入两个参数, 第…

【系统集成项目管理工程师】项目成本管理

💥十大知识领域:项目成本管理 主要考计算题 项目进度管理包括以下 4 个过程: 制订成本管理计划成本估算成本预算成本控制 一、制订成本管理计划 制订了项目成本结构、估算、预算和控制的标准 输入工具与技术输出项目管理计划项目章程事业环境因素组织过…

拼凑出来的低代码平台,真的好用吗?(浅谈行业怪象)

0️⃣前言 这几年低代码概念非常火热,市面上的低代码平台如雨后春笋应运而生,有许多身边的朋友对我说:“未来的研发方式一定是低代码的、低技术门槛的,低代码开发是一项技术革新。 ” 然而,就在我打算对它进行深入研究…

【业务数据分析】——十大常用数据分析方法

目录 一、数据分析方法 二、营销管理方法论 1、SWOT分析 2、PEST分析 3、4P理论 三、常用数据分析方法论 1、公式拆解 2、对比分析 3、A/Btest 4、象限分析 5、帕累托分析 6、漏斗分析 7、路径分析 8、留存分析 9、5W2H分析法 10、麦肯锡逻辑树分析法 一、数据…

基于html+css的图片展示23

准备项目 项目开发工具 Visual Studio Code 1.44.2 版本: 1.44.2 提交: ff915844119ce9485abfe8aa9076ec76b5300ddd 日期: 2020-04-16T16:36:23.138Z Electron: 7.1.11 Chrome: 78.0.3904.130 Node.js: 12.8.1 V8: 7.8.279.23-electron.0 OS: Windows_NT x64 10.0.19044 项目…

4.4 埃尔米特插值

为什么有埃尔米特插值法: 埃尔米特插值法是一种常用的数值方法,主要用于在给定的数据点集上构造一个可微的函数来近似描述这些数据点的趋势和特征。埃尔米特插值法有以下几个优点: 精度高:埃尔米特插值法可以通过给定数据点的函数…

如何在个人web项目中使用会话技术(cookiesession)?

编译软件:IntelliJ IDEA 2019.2.4 x64 操作系统:win10 x64 位 家庭版 服务器软件:apache-tomcat-8.5.27 目录 一. 什么是会话?二. 为什么要使用会话技术?三. 如何使用会话技术?3.1 Cookie(客户端的会话技术…

springboot+vue 个人健康信息管理系统

系统分为用户和医师,管理员三个角色 管理员的主要功能有: 1.管理员输入账户登陆后台 2.个人中心:管理员修改密码和账户信息 3.用户管理:对注册的用户信息进行添加,删除,修改,查询 4.医师管理&am…

seo文章批量更新-SEO文章自动批量生成

使用SEO文章生成器,让您的网站排名更靠前! 您是否对搜索引擎排名感到困扰?难道您想要网站排名更好,但却没有足够的时间和资源进行SEO优化吗?那么您需要尝试使用SEO文章生成器来帮助您的网站获得更好的排名&#xff01…

数据结构(二)—— 链表

文章目录 一、链表基础1.1 链表定义1.2 创建链表1.3 删除链表某一节点1.4 与数组的对比二、题2.1 203 移除链表元素2.2 707 设计链表2.3 206 反转单链表2.4 24 两两交换链表中的节点2.5 9 删除链表的倒数第N个节点2.6 面试题 02.07. leetcode160 链表相交2.7 142 环形链表II2.7…

Verilog带参数的`define用法

宏除了可以进行简单的文本替换,还可以像函数和任务一样传递指定多个参数分别对文本进行对应的替换. 示例1: define Disp(pa,pb,pc) \initial \begin \#1200; \$display("%d \n",(papbpc)); \$display(" data_ pa data_ pb data_ pc %d",(…

微信小程序 基于Promise 对 wx.request 封装处理

导语: 当我们进行微信小程序开发的时候,会经常涉及到发送网络请求来进行后台数据交互,而在微信小程序中,用来 发送请求的方法是 wx.request() , 但是由于 wx.request() 方法 不支持 Promise 风格的调用,所以导致 wx.re…

【C++从0到王者】第一站:从C到C++

目录 一、命名空间 1.C的命名缺陷 2.域和命名空间 3.命名空间的使用与嵌套 二、输入输出 三、缺省参数(默认参数) 1.缺省参数的概念 2.缺省参数分类 1>全缺省参数 2>半缺省参数 3.缺省参数的一些使用场景 4.缺省参数在分文件使用的注意…

系统运维(Docker篇)

前言 打怪升级之路,从未停息 ​ 在这个社会信息技术的发展速度越来越快,这种快速发展带来了激烈的竞争。在这个竞争性的环境中,只有不断学习和更新自己的技能,才能保持竞争力。其次随着云计算、容器化、自动化等技术的出现&…

Qt Quick - 容器控件综述

Qt Quick - 容器控件综述 一、概述二、ApplicationWindow Control三、Frame Control四、GroupBox Control五、Page Control六、Pane Control七、ScrollView Control八、StackView Control九、SwipeView Control十、TabBarControl十一、ToolBar控件 一、概述 Qt Quick Controls…

Linux基础——FTP原理与配置

Linux基础——FTP原理与配置 一、文件传输协议——FTP服务二、ftp配置文件解析三、FTP服务器搭建 一、文件传输协议——FTP服务 FTP是典型的C/S结构的应用层协议,需要由服务器软件、客户端软件两个部分共同实现文件传输功能 FTP 连接模式 FTP服务器默认使用TCP协议…

设计师找灵感,就上这5个网站~

分享5个设计灵感网站,多看看设计大佬的优秀作品,对提升审美、灵感都有很大的帮助,还可以结合好的设计运用到自己的作品当中,话不多说,上干货~ (PS:部分网站需要科学上网才能访问~) …

celery简单入门

celery B站连接:https://www.bilibili.com/video/BV1jg4y13718?p7&spm_id_frompageDriver&vd_source1717654b9cbbc6a773c2092070686a95 创建项目celery_project 一、新建一个celery_task.py文件 二、新建一个produce_task.py文件 三、新建一个result.py…