Java GC-常见垃圾回收器

目录

    • 前言
    • 一、垃圾回收器分类
    • 二、垃圾回收器介绍
      • 1、Serial 收集器
      • 2、ParNew 收集器
      • 3、Parallel Scavenge 收集器
      • 4、Serial Old 收集器
      • 5、Parallel Old 收集器
      • 6、CMS 收集器(多线程标记清除算法)
      • 7、G1 收集器
    • 三、项目中垃圾收集器选型

前言

      Java的垃圾回收器其作用是,用于回收程序在运行时所产生的垃圾对象(无引用的对象),因为Java程序一般情况下不用自己释放内存会交由垃圾回收器处理,针对不同业务可以选择不同的垃圾回收器,本文会对Java常见的几种垃圾回收器做介绍

一、垃圾回收器分类

  • Java的垃圾回收器大致可以按照三个维度划分,每种垃圾回收器都有自己的特点。
    按照所负责回收区域划分:新生代回收器,老年代回收器
    按照GC执行的资源成本划分:单线程回收,多线程回收
    按照与用户线程关系划分:需暂停用户线程,与用户线程并发
收集器回收区域收集算法回收器特征
Serial新生代标记-复制单线程
ParNew新生代标记-复制单线程
Parallel Scavenge新生代标记-复制单线程
Serial Old老年代标记-整理单线程
Parallel Old老年代标记-整理多线程
CMS老年代标记-清除并发多线程
G1
(JDK1.7推出,
JDK1.9默认垃圾回收器)
跨代回收整体:标记-整理
局部Region:标记-复制
并发多线程

在这里插入图片描述

二、垃圾回收器介绍

1、Serial 收集器

    这是一个单线程的垃圾回收器,即执行垃圾回收操作时只有一个GC线程工作,最重要的是在他执行GC过程中,必须全程暂停用户线程,也就是经常说的STW(Stop the world)问题,这是jvm最早期的收集器,虽然STW问题是确实是一个诟病,但是这种方案实现起来较简单,占用资源也是最小的,对应新生代内存比较小的应用中,相对比较适用,比如运行在客户端模式下的Java程序。
在这里插入图片描述

2、ParNew 收集器

    和Serial 收集器不同的是,这是一款多线程收集器,即有多条GC线程同时进行垃圾回收工作,剩余其他的特点和Serial 收集器基本无异,比如控制参数,回收算法,STW问题等,作为一款新生代收集器,常用来和CMS搭配使用,ParNew是激活CMS后默认的新生代收集器,由于多线程执行的原因,在单核CPU下,由于线程上下文的切换,该收集器的效果甚至不如Serial收集器,在多核CPU中才推荐使用。
在这里插入图片描述

3、Parallel Scavenge 收集器

    Parallel Scavenge与ParNew实现上差别不大,不同的是,该收集器的侧重点是虚拟机的吞吐量,吞吐量很好理解,即用户代码的执行时间占整个系统运行时间的比重,其中就包括GC时间。如果虚拟机运行期间GC消耗的时间,占用的资源相对较高,那吞吐量自然也就会下降。而Parallel Scavenge关注的就是吞吐量的可控,尽可能的减少GC时间,让用户线程执行更长的时间,一些交互性比较弱的应用,比如科学计算、批处理任务、订单流转等。
为了实现这个目标,Parallel Scavenge提供了一些参数:
-XX:MaxGCPauseMills 即“最大GC停顿毫秒值” , 该值设置的大小是以新生代回收空间为代价的,设置的值越小,意味着所能回收的空间也会越小,相应的GC频率自然会提高,这个时候未必会提高吞吐量,具体的设置多少,需要根据应用的实际场景来决定
-XX:GCTimeRatio 该参数的范围是大于0小于100的整数,意义是用户程序的运行时间和垃圾回收时间的比例,比如设置为99,那最大允许的垃圾回收时间为1%。
-XX:+UseAdaptiveSizePolicy 直译过来就是“自适应大小策略”,当这个参数被激活后,就不需要指定新生代、Eden和Survivor区的比例(-XX:SurvivorRatio)、晋升老年代对象大小(-XX:PretenureSizeThreshold)等参数,虚拟机会根据当前的运行状态,收集性能监控信息,动态调整这些参数以提供最合适的停顿时间和最大吞吐量。
在这里插入图片描述

4、Serial Old 收集器

    Serial Old 是 Serial 垃圾收集器年老代版本,它同样是个单线程的收集器,使用标记-整理算法,这个收集器也主要是运行在 Client 默认的 java 虚拟机默认的年老代垃圾收集器。
    在 Server 模式下,主要有两个用途:1. 在 JDK1.5 之前版本中与新生代的 Parallel Scavenge 收集器搭配使用。2. 作为年老代中使用 CMS 收集器的后备垃圾收集方案

  • 新生代 Serial 与年老代 Serial Old 搭配垃圾收集过程:
    在这里插入图片描述
  • 新生代 Parallel Scavenge/ParNew 与年老代 Serial Old 搭配垃圾收集过程:
    在这里插入图片描述

5、Parallel Old 收集器

    Parallel Old 收集器是Parallel Scavenge的年老代版本,使用多线程的标记-整理算法,在 JDK1.6才开始提供。在 JDK1.6 之前,新生代使用 ParallelScavenge 收集器只能搭配年老代的 Serial Old 收集器,只能保证新生代的吞吐量优先,无法保证整体的吞吐量,Parallel Old 正是为了在年老代同样提供吞吐量优先的垃圾收集器,如果系统对吞吐量要求比较高,可以优先考虑新生代 Parallel Scavenge和年老代 Parallel Old 收集器的搭配策略。
在这里插入图片描述

6、CMS 收集器(多线程标记清除算法)

    Concurrent mark sweep(CMS) 收集器是一种周期性老年代垃圾收集器,其最主要目标是获取最短垃圾回收停顿时间,和其他年老代使用标记-整理算法不同,它使用多线程的标记-清除算法。最短的垃圾收集停顿时间可以为交互比较高的程序提高用户体验。

  • CMS垃圾回收器垃圾回收主要分为4个阶段:
    • 1、初始标记:只是标记一下 GC Roots 能直接关联的对象,速度很快,仍然需要暂停所有的工作线程。
    • 2、并发标记:该阶段GC线程和应用线程并发执行,遍历初始标记阶段标记出来的存活对象,然后继续递归标记这些对象可达的对象。
    • 3、重新标记:为了修正在并发标记期间,因用户程序继续运行而导致标记产生变动的那一部分对象的标记记录,仍然需要暂停所有的工作线程,但是因为在前面两个阶段已经将大部分对象已经标记,这一步虽然需要暂停用户线程,但是这个暂停时间也不会很长。
    • 4、并发清除:这个阶段就是真正的清除垃圾对象的阶段,和用户线程一起工作,不需要暂停工作线程,会将前几步标记的垃圾对象清除。
      在这里插入图片描述

7、G1 收集器

    (Garbage first)G1 垃圾收集器采用了分区(Region)的思路,将整个堆空间分成若干个大小相等的内存区域(1MB~32MB,且必须是2的幂),每个Region根据需要都可以称为新生代的Eden区、Suivivor区,或者老年代区,收集器能够对扮演不同角色的Region采用不同的策略去处理,这样无论是新创建的对象,还是已经存活了一段时间的对象都能获得良好的收集效果。

    同时Region还有一类特殊的humongous区域,专门用来存储大对象,只要超过了一个Region容量的一半就会被认为是大对象,如果对象长度超过了Region的大小,则会使用多个连续的humongous来存放,G1的大多数行为会把该区域当做老年代来看待。

    G1依然保留了新生代和老年代的概念,逻辑上分代,物理上分区,内存中新生代和老年代不是固定的,他们是一系列的“动态集合”,通过这个动态集合建立一个可预测的停顿时间模型,换句话说,G1的回收是建立在这个停顿时间模型上的。每次回收都是以Region为单位,让G1去跟踪每一个Region中垃圾的“价值大小”,比如回收空间大小和回收所需的时间,然后通过这个价值大小维护一个优先级的列表,每次根据用户设定允许的收集停顿时间,优先处理回收价值最大的那些Region,这种划分Region空间以及具有优先级的区域回收方式,使得G1在有限时间内尽可能获得更高的收集效率。

  • G1垃圾回收执行过程可分为以下四步:
    • 初始标记:标记gc roots直接关联的对象,修改TAMS指针的值,目的是下阶段并发回收时,能够继续正常的分配对象。这个阶段需要停顿用户线程,但是相对比较短暂。
    • 并发标记:从gc roots开始对对象图进行可达性分析,找到有回收的对象,这个阶段与用户线程并发。
    • 最终标记:对并发标记时引用发生变化的对象重新标记,通过原始快照的方式,毫无疑问,这阶段需要短暂暂停用户线程
    • 筛选回收:负责更新Region的统计数据,对各个Region的回收价值和成本进行排序,结合用户指定的停顿时间制定回收计划,可以自由选择任意多个region构成回收集,然后把决定回收的那一部分region中存活的对象复制到空的region中,再清理掉整个旧region空间,由于要移动对象,所以这个阶段也必须暂停用户线程,有多个收集器线程并行完成 。
      在这里插入图片描述
      通过以上过程可以看出,除了并发标记阶段,其他阶段都需要暂停用户线程,所以G1主要目标是在延迟可控的情况下获得尽可能高的吞吐量,希望在延迟和吞吐量之间达到一个平衡。

三、项目中垃圾收集器选型

  • 如何合理选择收集器(项目配置堆内存有关系):
    • 1、入门级别网站 0.5-1GB,可以使用单线程新生代:Serial、老年代:Serial Old
    • 2、有一定的访问量 1-4G,新生代:ParNew | Parallel Scavenge、老年代:Parallel Old
    • 3、并发适中 4G左右,新生代:ParNew | Parallel Scavenge、老年代:CMS(响应式优先)
    • 4、高并发项目8G以上,G1收集器(注重吞吐和响应时间)

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

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

相关文章

蓝桥杯每日一题-----数位dp

前言 今天浅谈一下数位dp的板子,我最初接触到数位dp的时候,感觉数位dp老难了,一直不敢写,最近重新看了一些数位dp,发现没有想象中那么难,把板子搞会了,变通也会变的灵活的多! 引入…

如何以管理员身份删除node_modules文件

今天拉项目,然后需要安装依赖,但是一直报错,如下: 去搜这个问题会让把node_modules文件先删掉 再去安装依赖。我在删除的过程中会说请以管理员身份来删除。 那么windows如何以管理员身份删除node_modules文件呢? wi…

Python绘制热力图

最近投SCI论文的时候,有些实验结果需要热力图展示,所以专门试了一下如何用python绘制热力图,发现简单好用,下面分享给大家具体方法。 一、安装python库 需要安装pandas、seaborn、matplotlib安装包依赖,均用pip一键安…

深入了解 Ansible:全面掌握自动化 IT 环境的利器

本文以详尽的篇幅介绍了 Ansible 的方方面面,旨在帮助读者从入门到精通。无论您是初学者还是有一定经验的 Ansible 用户,都可以在本文中找到对应的内容,加深对 Ansible 的理解和应用。愿本文能成为您在 Ansible 自动化旅程中的良师益友&#…

vue学习91-105

vue的基本认知p91 创建一个空仓库p93 vue 路由 vuex版本 2 3 3 3 4 4 npm的vuex装包npm install vuex --save vuex里有仓库,仓库放vuex核心代码,所有组件都能访问到 const store new Vuex.Store()//访问stored this.$store如何提供$访问vuex的数据p94 核心概念-…

GNSS模块的惯导技术:引领定位科技的前沿

全球导航卫星系统(GNSS)模块的惯导技术是一项颇具前瞻性的科技,它结合了全球定位系统和惯性导航技术,为各个领域的定位需求提供了更为精准和可靠的解决方案。本文将深入探讨GNSS模块的惯导技术,以及它如何在多个领域中…

DATAX改造支持geometry类型数据同步

数据库使用postgresql安装了postgis插件存储了geometry空间数据,想使用datax做数据同步,但datax本身不支持geometry类型数据,如何改造呢? 1.首先下载已改造支持geometry类型的datax引擎,下载地址 https://download.c…

微信小程序之本地生活案例的实现

学习的最大理由是想摆脱平庸,早一天就多一份人生的精彩;迟一天就多一天平庸的困扰。各位小伙伴,如果您: 想系统/深入学习某技术知识点… 一个人摸索学习很难坚持,想组团高效学习… 想写博客但无从下手,急需…

关于《人工智能法案》你应该知道的真相

什么是《人工智能法案》 《人工智能法案》是欧盟的一项法规,旨在为人工智能引入一个共同的监管和法律框架,保障人类的安全、健康和基本权利,同时促进人工智能的创新和发展。该法案根据人工智能应用可能造成的风险,对其进行了不同…

AcWing算法学习笔记:动态规划(背包 + 线性dp + 区间dp + 计数dp + 状态压缩dp + 树形dp + 记忆化搜索)

动态规划 一、背包问题① 01背包朴素版② 01背包优化版③ 完全背包朴素版④ 完全背包消k版⑤ 完全背包消k优化版⑥ 多重背包朴素版⑦多重背包二进制优化版⑧ 分组背包朴素版⑨ 分组背包优化版 二、线性dp① 数字三角形② 最长上升子序列③ 最长上升子序列打印序列版④ 最长上升…

Pytest自动化测试详解

🍅 视频学习:文末有免费的配套视频可观看 🍅 关注公众号:互联网杂货铺,回复1 ,免费获取软件测试全套资料,资料在手,涨薪更快 为什么需要自动化测试? 自动化测试有很多优…

CSS 闪电按钮效果

<template><view class="const"><div class="voltage-button"><button>闪电按钮</button><svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" viewBox=&q…

02.04

1.信号 include "myhead.h" //定义信号处理函数 void handler(int signo) {if(signo SIGINT){printf("用户按下了ctrl c键&#xff0c;hello world\n");} }int main(int argc, const char *argv[]) {if(signal(SIGINT, handler) SIG_ERR){perror("…

vue前端+nodejs后端通信-简单demo

本文记录vue前端nodejs后端通讯最简单的方法&#xff0c;供广大网友最快速进入全栈开发。 技术架构 前端 vue axios 后端 nodejs express 一、前端部分-搭建VUE 项目 vue create Vnodenpm run serve 启动&#xff1b; 具体操作步骤&#xff0c;请自行百度&#xff0c;这里没…

【JavaEE spring】SpringBoot 统一功能处理

SpringBoot 统一功能处理 1. 拦截器1.1 拦截器快速⼊⻔1.2 拦截器详解1.2.1 拦截路径1.2.2 拦截器执⾏流程 1.3 登录校验1.3.1 定义拦截器1.3.2 注册配置拦截器 2. 统⼀数据返回格式2.1 快速⼊⻔2.2 存在问题2.3 案例代码修改2.4 优点 3. 统⼀异常处理 1. 拦截器 后端程序根据…

快递员的烦恼 - 华为OD统一考试

OD统一考试&#xff08;C卷&#xff09; 分值&#xff1a; 200分 题解&#xff1a; Java / Python / C 题目描述 快递公司每日早晨&#xff0c;给每位快递员推送需要淡到客户手中的快递以及路线信息&#xff0c;快递员自己又查找了一些客户与客户之间的路线距离信息&#xff0…

怎么把物品信息图片批量生成二维码?每张图片单独生码的制作技巧

现在通过扫码来查看人员或者物品信息的方式越来越常见&#xff0c;在合适的位置放置对应的二维码内容&#xff0c;让其他人通过扫码来获取图片信息。那么如果我们将每个信息做成一张图片后&#xff0c;需要将图片生成二维码时&#xff0c;有能够批量生成二维码的方法可以快速处…

【Mysql】整理

Mysql整理与总结 整理Mysql的基本内容供回顾。 参考&#xff1a; [1]. 掘金.MySQL三大日志(binlog,redolog,undolog)详解 [2]. Javaguide.MySQL三大日志(binlog、redo log和undo log)详解

2023-12蓝桥杯STEMA考试 C++ 中高级试卷解析

蓝桥杯STEMA考试 C++ 中高级试卷(12月) 一、选择题 第一题 定义字符串 string a = "Hello C++",下列选项可以获取到字符 C 的是(B)。 A、a[7] B、a[6] C、a[5] D、a[4] 第二题 下列选项中数值与其它项不同的是( C)。 A、 B、 C、 D、 第三题 定义变量 int i =…

幻兽帕鲁服务器自动重启备份-python

幻兽帕鲁服务器自动重启备份-python 1. 前置知识点2. 目录结构3. 代码内容4. 原理解释5. 额外备注 基于python编写的服务器全自动管理工具&#xff0c;能够实现自动定时备份存档&#xff0c;以及在检测到服务器崩溃之后自动重新启动&#xff0c;并且整合了对于frp端口转发工具的…