JVM - 垃圾回收

news2024/11/25 0:54:47

目录

垃圾回收基础和根搜索算法

垃圾回收概述

根搜索算法

引用分类

垃圾回收基础(跨代引用、记忆集、写屏障、判断垃圾的步骤、STW)

跨代引用

记忆集(Remembered Set)

写屏障

判断是否垃圾的步骤

GC类型

Stop-The-World

垃圾收集类型

判断类无用的条件

垃圾回收算法

标记清除法

复制算法

分配担保

标记整理法

垃圾收集器基础和串行收集器

并行收集器和Parallel Scavenge收集器

并行收集器

新生代Parallel Scavenge收集器

CMS收集器

G1收集器

ZGC收集器、GC性能指标和JVM内存配置原则

ZGC收集器

GC性能指标

JVM内存配置原则


  • 垃圾回收基础和根搜索算法

  • 垃圾回收概述

  • 什么是垃圾:
    • 简单来说就是内存中已经不再被使用到的内存空间就是垃圾
  • 引用计数法:
    • 给对象添加一个引用计数器,有访问就加1,引用失效就减1
  • 优点:实现简单、效率高
  • 缺点:不能解决对象之间循环引用的问题
  • 根搜索算法

  • 从根(GC Roots)节点向下搜索对象节点,搜索走过的路经称为引用链,当一个对象到根之间没有连通的话,则该对象不可用
  • 示意图:

  • 可作为GC Roots的对象包括:虚拟机栈(栈帧局部变量)中引用的对象、方法区类静态属性引用的对象、方法区中常量引用的对象、本地方法栈中JNI引用的对象
  • HotSpot使用了一组叫做OopMap的数据结构达到准确式GC的目的
  • 在OopMap的协助下,JVM可以很快的做完GC Roots枚举
  • 但是JVM并没有为每一条指令生成一个OopMap
  • 记录OopMap的这些“特定位置”被称为安全点,即当前线程执行到安全点后才允许暂停进行GC
  • 如果一段代码中,对象引用关系不会发生变化,这个区域中任何地方开始GC都是安全的,那么这个区域称为安全区域
  • 引用分类

  • 强引用:
    • 类似于Object a = new A()这样的,不会被回收
  • 软引用:
    • 还有用但并不必须的对象;用SoftReference来实现软引用
  • 弱引用:
    • 非必须对象,比软引用还要弱,垃圾回收时会回收掉;用WeakReference来实现弱引用
  • 虚引用:
    • 也称为幽灵引用或幻影引用,是最弱的引用;垃圾回收时会回收掉;用PhantomReference来实现虚引用
  • 垃圾回收基础(跨代引用、记忆集、写屏障、判断垃圾的步骤、STW)

  • 跨代引用

  • 也就是一个代中的对象引用另一个代中的对象
  • 跨代引用假说:
    • 跨代引用相对于同代引用来说只是极少数
  • 隐含推论:
    • 存在互相引用关系的两个对象,是应该倾向于同时生存或同时消亡的
  • 记忆集(Remembered Set)

  • 一种用于记录从非收集区域指向收集区域的指针集合的抽象数据结构
  • 字长精度:
    • 每个记录精确到一个机器字长,该字包含跨代指针
  • 对象精度:
    • 每个记录精确到一个对象,该对象里有字段含有跨代指针
  • 卡精度:
    • 每个记录精确到一块内存区域,该区域内有对象含有跨代指针
  • 卡表(Card Table):
    • 是记忆集的一种具体实现,定义了记忆集的记录精度和与堆内存的映射关系等
  • 卡表的每个元素都对应着其标识的内存区域中一块特定大小的内存块,这个内存块称为卡页(Card Page)
  • 写屏障

  • 可以看成是JVM对“引用类型字段赋值”这个动作的AOP
  • 通过写屏障来实现当对象状态改变后,维护卡表状态
  • 判断是否垃圾的步骤

    • (1)根搜索算法判断不可用
    • (2)看是否有必要执行finalize方法
    • (3)两个步骤走完后对象仍然没有人使用,那就属于垃圾
  • GC类型

  • MinorGC/YoungGC:
    • 发生在新生代的收集动作
  • MajorGC/OldGC:
    • 发生在老年代的GC,目前只有CMS收集器会有单独收集老年代的行为
  • MixedGC:
    • 收集整个新生代以及部分老年代,目前只有G1收集器会有这种行为
  • FullGC:
    • 收集整个Java堆和方法区的GC
  • Stop-The-World

  • STW是Java中一种全局暂停的现象,多半由于GC引起
  • 所谓全局停顿,就是所有Java代码停止运行,native代码可以执行,但不能和JVM交互
  • 其危害是长时间服务停止,没有响应;对于HA系统,可能引起主备切换,严重危害生产环境
  • 垃圾收集类型

  • 串行收集:
    • GC单线程内存回收、会暂停所有的用户线程,如:Serial
  • 并行收集:
    • 多个GC线程并发工作,此时用户线程是暂停的,如:Parallel
  • 并发收集:
    • 用户线程和GC线程同时执行(不一定是并行,可能交替执行),不需要停顿用户线程,如:CMS
  • 判断类无用的条件

  • JVM中该类的所有实例都已经被回收
  • 加载该类的ClassLoader已经被回收
  • 没有任何地方引用该类的Class对象
  • 无法在任何地方通过反射访问这个类
  • 垃圾回收算法

  • 标记清除法

  • 标记清除法(Mark-Sweep)算法分成标记和清除两个阶段,先标记出要回收的对象,然后统一回收这些对象
  • 示意图:

  • 优点是简单
  • 缺点是:
    • 效率不高,标记和清除的效率都不高
    • 标记清除后会产生大量不连续的内存碎片,从而导致在分配大对象时触发GC
  • 复制算法

  • 复制算法(Copying):把内存分成两块完全相同的区域,每次使用其中一块,当一块使用完了,就把这块上还存活的对象拷贝到另外一块,然后把这块清除掉
  • 示意图:

  • 优点是:
    • 实现简单,运行高效,不用考虑内存碎片问题
  • 缺点是:
    • 内存有些浪费
  • JVM实际实现中,是将内存分为一块较大的Eden区和两块较小的Survivor空间,每次使用Eden和一块Survivor,回收时,把存活的对象复制到另一块Survivor
  • HotSpot默认的Eden和Survivor比是8:1,也就是每次能用90%的新生代空间
  • 如果Survivor空间不够,就要依赖老年代进行分配担保,把放不下的对象直接进入老年代
  • 分配担保

  • 当新生代进行垃圾回收后,新生代的存活区放置不下,那么需要把这些对象放置到老年代去的策略,也就是老年代为新生代的GC做空间分配担保
  • 步骤如下:
  • (1)在发生MinorGC前,JVM会检查老年代的最大可用的连续空间,是否大于新生代所有对象的总空间,如果大于,可以确保MinorGC是安全的
  • (2)如果小于,那么JVM会检查是否设置了允许担保失败,如果允许,则继续检查老年代最大可用的连续空间,是否大于历次晋升到老年代对象的平均大小
  • (3)如果大于,则尝试进行一次MinorGC
  • (4)如果不大于,则改做一次Full GC
  • 标记整理法

  • 标记整理算法(Mark-Compact):由于复制算法在存活对象比较多的时候,效率较低,且有空间浪费,因此老年代一般不会选用复制算法,老年代多选用标记整理算法
  • 标记过程跟标记清除一样,但后续不是直接清除可回收对象,而是让所有存活对象都向一端移动,然后直接清除边界以外的内存
  • 示意图:

  • 垃圾收集器基础和串行收集器

  • 前面讨论的垃圾收集算法只是内存回收的方法
  • 垃圾收集器就来具体实现这些算法并实现内存回收
  • 不同厂商、不同版本的虚拟机实现差别很大,HotSpot中包含的收集器如下图所示:

  • Serial(串行)收集器/Serial Old收集器
  • 是一个单线程的收集器,在垃圾收集时,会Stop-the-World
  • 运行示意图:

  • 优点是简单,对于单cpu,由于没有多线程的交互开销,可能更高效,是默认的Client模式下的新生代收集器
  • 使用-XX:+UseSerialGC来开启,会使用:Serial + SerialOld的收集器组合
  • 新生代使用复制算法,老年代使用标记-整理算法
  • 并行收集器和Parallel Scavenge收集器

  • 并行收集器

  • ParNew(并行)收集器:
  • 使用多线程进行垃圾回收,在垃圾收集时,会Stop-the-World
  • 示意图:

  • 在并发能力好的CPU环境里,它停顿的时间要比串行收集器短
  • 但对于单cpu或并发能力较弱的CPU,由于多线程的交互开销,可能比串行回收器更差
  • 是Server模式下首选的新生代收集器,且能和CMS收集器配合使用
  • 不再使用-XX:+UseParNewGC来单独开启
  • -XX:ParallelGCThreads:指定线程数,最好与CPU数量一致
  • 新生代使用复制算法
  • 新生代Parallel Scavenge收集器

  • 新生代Parallel Scavenge收集器/Parallel Old收集器:是一个应用于新生代的、使用复制算法的、并行的收集器
  • 跟ParNew很类似,但更关注吞吐量,能最高效率的利用CPU,适合运行后台应用
  • 示意图:

  • 使用-XX:+UseParallelGC来开启
  • 使用-XX:+UseParallelOldGC来开启老年代使用ParallelOld收集器
  • 使用Parallel Scavenge + Parallel Old的收集器组合
  • -XX:MaxGCPauseMillis:设置GC的最大停顿时间
  • 新生代使用复制算法,老年代使用标记-整理算法
  • CMS收集器

  • CMS(Concurrent Mark and Sweep 并发标记清除)收集器分为:
  • 初始标记:只标记GC Roots能直接关联到的对象
  • 并发标记:进行GC Roots Tracing的过程
  • 重新标记:修正并发标记期间,因程序运行导致标记发生变化的那一部分对象
  • 并发清除:并发回收垃圾对象
  • 示意图:

  • 在初始标记和重新标记两个阶段还是会发生Stop-the-World
  • 使用标记清除算法,多线程并发收集的垃圾收集器
  • 最后的重置线程,指的是清空跟收集相关的数据并重置,为下一次收集做准备
  • 优点:低停顿、并发执行
  • 缺点:
  • 并发执行,对CPU资源压力大
  • 无法处理在处理过程中产生的垃圾,可能导致FullGC
  • 采用的标记清除算法会导致大量碎片,从而在分配大对象时可能触发FullGC
  • 开启:-XX:UseConcMarkSweepGC:
  • 使用ParNew + CMS + Serial Old的收集器组合,Serial Old将作为CMS出错的后备收集器
  • -XX:CMSInitiatingOccupancyFraction:设置CMS收集器在老年代空间被使用多少后触发回收,默认80%
  • G1收集器

  • G1(Garbage-First)收集器:是一款面向服务端应用的收集器,与其它收集器相比,具有如下特点:
  • (1)G1把内存划分成多个独立的区域(Region)
  • (2)G1仍采用分代思想,保留了新生代和老年代,但它们不再是物理隔离的,而是一部分Region的集合,且不需要Region是连续的
  • (3)G1能充分利用多CPU、多核环境硬件优势,尽量缩短STW
  • (4)G1整体上采用标记-整理算法,局部是通过复制算法,不会产生内存碎片
  • (5)G1的停顿可预测,能明确指定在一个时间段内,消耗在垃圾收集上的时间不能超过多长时间
  • (6)G1跟踪各个Region里面垃圾堆的价值大小,在后台维护一个优先列表,每次根据允许的时间来回收价值最大的区域,从而保证在有限时间内的高效收集
  • 跟CMS类似,也分为四个阶段:
    • 初始标记:只标记GCRoots能直接关联到的对象
    • 并发标记:进行GC Roots Tracing的过程
    • 最终标记:修正并发标记期间,因程序运行导致标记发生变化的那一部分对象
    • 筛选回收:根据时间来进行价值最大化的回收
  • 示意图:

  • 使用和配置G1:-XX:+UseG1GC:开启G1,默认就是G1
  • -XX:MaxGCPauseMillis=n:最大GC停顿时间,这是个软目标,JVM将尽可能(但不保证)停顿小于这个时间
  • -XX:InitiatingHeapOccupancyPercent=n:堆占用了多少的时候就触发GC,默认为45
  • -XX:NewRatio=n:默认为2
  • -XX:SurvivorRatio=n:默认为8
  • -XX:MaxTenuringThreshold=n:新生代到老年代的岁数,默认是15
  • -XX:ParallelGCThreads=n:并行GC的线程数,默认值会根据平台不同而不同
  • -XX:ConcGCThreads=n:并发GC使用的线程数
  • -XX:G1ReservePercent=n:设置作为空闲空间的预留内存百分比,以降低目标空间溢出的风险,默认值是10%
  • -XX:G1HeapRegionSize=n:设置的G1区域的大小
  • 值是2的幂,范围是1MB到32MB
  • 目标是根据最小的Java堆大小划分出约2048个区域
  • ZGC收集器、GC性能指标和JVM内存配置原则

  • ZGC收集器

  • ZGC收集器:JDK11加入的具有实验性质的低延迟收集器
  • ZGC的设计目标是:支持TB级内存容量,暂停时间低(<10ms),对整个程序吞吐量的影响小于15%
  • ZGC里面的新技术:着色指针和读屏障
  • GC性能指标

  • 吞吐量=应用代码执行的时间/运行的总时间
  • GC负荷,与吞吐量相反,是GC时间/运行的总时间
  • 暂停时间,就是发生Stop-the-World的总时间
  • GC频率,就是GC在一个时间段发生的次数
  • 反应速度,就是从对象成为垃圾到被回收的时间
  • 交互式应用通常希望暂停时间越少越好
  • JVM内存配置原则

  • 新生代尽可能设置大点,如果太小会导致:
  • (1)YGC次数更加频繁
  • (2)可能导致YGC后的对象进入老年代,如果此时老年代满了,会触发FGC
  • 对老年代,针对响应时间优先的应用:
    • 由于老年代通常采用并发收集器,因此其大小要综合考虑并发量和并发持续时间等参数
    • 如果设置小了,可能会造成内存碎片,高回收频率会导致应用暂停
    • 如果设置大了,会需要较长的回收时间
  • 对老年代,针对吞吐量优先的应用:
    • 通常设置较大的新生代和较小的老年代,这样可以尽可能回收大部分短期对象,减少中期对象,而老年代尽量存放长期存活的对象
  • 依据对象的存活周期进行分类,对象优先在新生代分配,长时间存活的对象进入老年代
  • 根据不同代的特点,选取合适的收集算法:
    • 少量对象存活,适合复制算法
    • 大量对象存活,适合标记清除或者标记整理

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

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

相关文章

Mybatis源码(2) - SqlSessionTemplate的介绍及创建过程

0. 前言1. Spring对SqlSessionTemplate的管理1.1. SqlSessionTemplate的创建&#xff1a;1.2. MapperProxy中sqlSession的来源&#xff1a;2. SqlSessionInterceptor中的getSqlSession0. 前言 众所周知&#x1f60f;:MyBatis通过SqlSessionFactory 创建SqlSession去调用Executo…

在VMware17 Pro中设置创建虚拟机Ubuntu 20

在VMware17 Pro中设置创建虚拟机Ubuntu 200 前言1 安装Ubuntu 20步骤0 前言 书接上回&#xff0c;安装好了VMware17 Pro之后&#xff0c;就是安装虚拟机了&#xff0c;前提是下好了系统安装包&#xff0c;以Ubuntu 20为例 1 安装Ubuntu 20步骤 首先点击创建新的虚拟机 新建…

利用NAS免费部署动态解析实现内网穿透

‍ 想要从外网访问家中的NAS等设备&#xff0c;一般来说我们需要知道家中路由器的公网IP。 现在固定的公网IP基本上很难免费申请到了&#xff0c;但是一般来说运营商可以免费提供一个动态变化的公网IP&#xff1a;当路由设备重启时&#xff0c;运营商会给你重新分配一个新的I…

PHP加载3D模型【WebGL】

这是另一篇关于如何使用 PHP加载 3D 模型的文章。 在这里&#xff0c;我使用 Laravel 作为后端及其存储。 我在前端使用 Three.Js 库来渲染和显示 3D 模型。 我将向您展示如何上传 3D 模型以及如何从 Laravel 存储加载 3D 模型。 请仔细完成以下步骤。 大家可以在评论区提出任何…

8Manage PPM项目管理系统独特的功能:项目完整性保护

项目有其内在复杂性&#xff08;项目管理的科学部分&#xff09;&#xff0c;这种复杂性可以进行划分和克服。项目也有人为的或偶然的复杂性&#xff08;项目管理的艺术部分&#xff09;&#xff0c;这种复杂性无法进行划分和克服。偶然的高复杂性会影响并使内在复杂性难以管理…

【系统架构设计师】计算机组成与体系结构 ① ( 计算机组成 | CPU | 存储器 | 总线 | IO 外设 | CPU 组成 | 运算器 | 控制器 )

文章目录一、计算机组成与体系结构二、计算机组成结构三、CPU 组成1、运算器2、控制器一、计算机组成与体系结构 计算机组成与体系结构 对应 大学的 计算机组成原理 课程 , 主要分为 : 计算机组成体系结构划分 两大知识板块 ; 在架构师考试时 , 平均分值是 3 分 ; 计算机组成…

三相可控全桥整流与DC Buck变换电路设计仿真问题汇总

目 录 问题 一、开关管没有打开的情况下&#xff0c;DC Buck输出负电压&#xff1f; 二、问题分析 1.输出端存在与母线电压反相的电压&#xff0c;因此可以确定为差模感应电压&#xff0c;如果输出端与母线端产生的是大小相等&#xff0c;方向相同的同相电压&#xff0c;则为共…

大数据框架之Hadoop:HDFS(六)DataNode(面试开发重点)

6.1DataNode工作机制 DataNode工作机制&#xff0c;如下图所示。 1&#xff09;一个数据块在DataNode上以文件形式存储在磁盘上&#xff0c;包括两个文件&#xff0c;一个是数据本身&#xff0c;一个是元数据包括数据块的长度&#xff0c;块数据的校验和&#xff0c;以及时间戳…

ROS笔记(4)——发布者Publisher与订阅者Subscribe的编程实现

发布者 以小海龟的话题消息为例,编程实现发布者通过/turtle1/cmd_vel 话题向 turtlesim节点发送消息&#xff0c;流程如图 步骤一 创建功能包&#xff08;工作空间为~/catkin_ws/src&#xff09; $ cd ~/catkin_ws/src $ catkin_create_pkg learning_topic roscpp rospy s…

FLStudio水果最新版本V21支持中文语言

FL Studio简称FL&#xff0c;全称&#xff1a;Fruity Loops Studio习惯叫它水果。软件现有版本是FLStudio21&#xff0c;已全面升级支持简体中文语言界面 。FL Studio 能让你的计算机就像是全功能的录音室一样&#xff0c;完成编曲、剪辑、录音、混音等工作&#xff0c;帮助爱好…

2023大厂高频软件测试面试真题(附答案)

一、接口测试面试题&#xff1a;1.接口测试是怎么做的&#xff0c;如何分析数据&#xff1f;接口测试实际跟一般测试不同就是测试用例的设计部分。获取接口规范。设计接口测试功能用例&#xff08;主要从用户角度出发看接口能否实现业务需求&#xff0c;用例设计就是黑盒用例那…

2022财年净新增1159家门店,百胜中国门店高速扩张背后有何阳谋?

中国最大餐饮企业百胜中国控股有限公司&#xff08;下称“百胜中国”&#xff09;&#xff0c;2月8日发布了2022年度第四季度及全年未经审核的财务业绩。 从财报数据来看&#xff0c;这家拥有肯德基、必胜客、黄记煌等诸多餐饮品牌的巨头&#xff0c;已经顺利渡过了疫情笼罩下…

计算机网络(第7版)第五章(物理层)知识点整理

计算机网络 参考书目&#xff1a;《计算机网络&#xff08;第7版&#xff09;》&#xff1a;谢希仁——电子工业出版社 《精通Windows Sockets网络开发--基于Visual C实现》&#xff1a;孙海民——人民邮电出版社 第五章&#xff1a;物理层计算机网络一、基本概念二、传输媒体…

和数集团打造《神念无界:源起山海》,诠释链游领域创新与责任

首先&#xff0c;根据网上资料显示&#xff0c;一部《传奇》&#xff0c;二十年热血依旧。 《传奇》所缔造的成绩&#xff0c;承载的是多少人的青春回忆&#xff0c;《传奇》无疑已经在游戏史上写下了浓墨重彩的一笔。 相比《传奇》及背后的研发运营公司娱美德名声大噪&#x…

uniapp上高德(百度)地图API的使用(APP安卓)

前言由于在app中没有document,window等对象&#xff0c;所以使用在pc端传统方法引入的方式&#xff0c;将会发现无法引用成功&#xff0c;会出现白屏现象。目前有两种解决方式&#xff1a;使用uniapp的web-view方式&#xff08;百度地图&#xff09;使用renderjs来调用document…

【51媒体网】媒体邀约行业诞生及其前景预测

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。一&#xff0c;媒体邀约行业的诞生媒体邀约行业是随着现代社会媒体的普及而逐渐形成的。随着互联网和社交媒体的快速发展&#xff0c;媒体作为信息传播的重要渠道之一&#xff0c;越来越成…

PPP协议实验及配置

PPP协议实验拓扑图PPP认证配置PAP认证CHAP认证接口地址不在一个网段&#xff1f;地址自动协商通过IPCP方式获取到默认路由拓扑图 首先在设备上增添两个Serial接口&#xff1a; PPP认证配置 PAP认证 AR1作为认证方&#xff0c;AR2作为被认证方&#xff1a; AR1&#xff1a…

Flask-SQLAlchemy的安装使用 一对多 多对多join查询

Flask-SQLAlchemy安装及设置 SQLALchemy 实际上是对数据库的抽象&#xff0c;让开发者不用直接和 SQL 语句打交道&#xff0c;而是通过 Python 对象来操作数据库&#xff0c;在舍弃一些性能开销的同时&#xff0c;换来的是开发效率的较大提升SQLAlchemy是一个关系型数据库框架…

yaml配置文件

最近在写代码&#xff0c;发现随着网络的增加&#xff0c;代码变得越来越冗余&#xff0c;所以就想着写一个网络的配置文件&#xff0c;把网络的配置放到一个文件中&#xff0c;而不再主函数中&#xff0c;这样代码开起来就好看了&#xff0c;调试的时候也方便了。之前写过一篇…

rollback-only异常令我对事务有了新的认识

背景 环境 相关环境配置&#xff1a; SpringBootPostGreSQL Spring Data JPA 问题 两个使用 Transaction 注解的 ServiceA 和 ServiceB&#xff0c;在 A 中引入了 B 的方法用于更新数据 &#xff0c;当 A 中捕捉到 B 中有异常时&#xff0c;回滚动作正常执行&#xff0c;但…