JVM专栏-3.垃圾收集器

news/2024/10/18 7:50:25/

在垃圾收集器的上下文中并发并行的意义

  • 并行(Parallel): 并行描述的是多条垃圾收集器线程之间的关系,说明同一时间有多条这样的线程在协同工作,通常默认此时用户线程是处于等待状态
  • 并发(Concurrent): 并发描述的是垃圾收集器线程和用户线程之间的关系,说明同一时间垃圾收集器线程和用户线程都在运行。由于用户线程并未被冻结,所以程序仍然能响应服务请求,但由于垃圾收集器线程占用了一部分系统资源,此时应用程序的处理的吞吐量将受到一定的影响

一.新生代收集器

1.Serial收集器

单线程垃圾收集器、最基本、发展最悠久。采用复制算法,它的单线程的意义并不仅仅说明它只会使用一个CPU或一条收集线程去完成垃圾收集工作,更重要的是在它进行垃圾收集时,必须暂停其他所有的工作线程(Stop The World),直到它收集结束。偶尔用在桌面应用中。

2.ParNew收集器

实质上就是 Serial收集器的多线程并行版本版本,所有的可控参数,收集算法,对象分配规则,回收策略与Serial收集器完全一直

可多线程收集垃圾,收集新生代,使用收集算法

3.Parallel Scavenge收集器

基于标记-复制算法也是能够并行收集的多线程收集器,

特点:

Parallel Scavenge收集器的目标是希望达到一个可控制的吞吐量(Throughput),所谓的吞吐量就是处理器用于运行用户代码的时间与处理器的总消耗时间的比值,多线程收集器,其注重点在于尽可能的缩短垃圾收集时用户线程的停顿时间。
吞吐量 = 运行用户代码时间 / (运行用户代码时间 + 运行垃圾收集时间) 吞吐量=运行用户代码时间 / (运行用户代码时间+运行垃圾收集时间) 吞吐量=运行用户代码时间/(运行用户代码时间+运行垃圾收集时间)
Parallel Scavenge 收集器提供了两个参数用于精确控制吞吐量:

- 控制垃圾收集停顿时间(允许的值是一个大于0的毫秒数,收集器将尽力保证内存回收花费的时间不超过用户设定值,但最大停顿时间过短必然会导致新生代的内存大小变小,垃圾回收频率变高,效率可能降低。)
-XX:MaxGCPauseMillis- 设置吞吐量大小(允许的值为一个正整数,表示用户期望虚拟机消耗在Gc上的时间不超过程序运行时间的1/(1+N),默认是99,含义就是收集器的时间消耗不超过总运行时间的1%)
-XX:GCTimeRatio

由于与吞吐量关系密切,Parallel Scavenge也被称为“吞吐量优先收集器”,该收集器还有一个参数为“-XX:+UseAdaptiveSizePolicy”,这是一个开关参数,激活该参数之后,就不需要人工指定新生代的大小等细节参数了,虚拟机会根据当前系统的运行情况收集性能监控信息,动态的调整这些参数以提供最合适的停顿时间或者最大的吞吐量。这种调节方式称为垃圾收集的自适应调节策略(GC Ergonomics),我们只需要配置内存基本信息(如设置-Xmx设置最大堆,然后使用-XX:MaxGCPauseMillis 参数或者-XX:GCTimeRation参数)具体细节参数的调节工作就由虚拟机完成了。

二.老年代收集器

4.Serial Old收集器

是Serial收集器的老年代版本,也是单线程收集器,采用标记-整理算法。

5.Parallel Old收集器

Parallel Scavenge收集器的老年代版本,也就是我们常常看到的(PS MarkSweep),支持多线程并行收集,基于标记-整理算法。

6.CMS收集器

Concurrent Mark Sweep,采用标记-清除算法,用于老年代,常与ParNew协同工作。
注:并行是指同一时刻同时做多件事情,而并发是指同一时间间隔内做多件事情

工作过程

  • 初始标记(需要STW)
    标记老年代中所有的GC Roots对象和年轻代中活着的对象引用到的老年代的对象,时间短;
  • 并发标记
    从“初始标记”阶段标记的对象开始找出所有存活的对象;
  • 重新标记(需要STW)
    用来处理前一个阶段因为引用关系改变导致没有标记到的存活对象,时间短;
  • 并发清理
    清除那些没有标记的对象并且回收空间。

优点:

并发收集,低停顿

缺点:

占用大量的cpu资源、无法处理浮点垃圾、出现Concurrent Mode Failure、空间碎片。

为什么会出现并发失败(Concurrent Mode Failure)?

因为在垃圾收集期间,用户线程还在持续运行,所以需要预留足够的内存空间给用户线程使用,如果预留的这部分内存无法满足程序分配新对象的需要,就会出现一次并发失败(Concurrent Mode Failure) ,这个是时候虚拟机将不得不开启后备预案,冻结用户线程,临时启用Serial Old 收集器来重新进行老年代的垃圾收集,所以参数-XXCMSInitiatingOccupancyFraction 的设置比例很重要。

7.G1收集器

G1(Garbage First)垃圾收集器是当今垃圾回收技术最前沿的成果之一,早在JDK7就已加入JVM的收集器大家庭中,JDK9中取代Parallel Scavenge 和Parallel Old组合成为默认垃圾收集器。

分代转分区

之前的垃圾收集器,进行收集的范围要么是整个新生代(Minor GC),要么就是整个老年代(Major GC) ,要么就是整个堆(Full GC),G1面向内存的任何部分组成回收集(Collection Set,一般称为CSet),进行回收,回收标准不再是判断属于那个分代,而是那块内存中存放的垃圾数量最多,回收的利益最大。

G1虽然也是遵循分代收集理论,但是不再以固定的大小和固定数量的分代区域划分,而是把连续的Java堆划分为多个大小相等的独立区域(Region),每一个region根据需要扮演新生代的Eden区,Survivor空间,或者老年代。

Humongous区

专门用来存储大对象,G1认为只要大小超过一个Region容量一半的对象即可判定为大对象。

工作过程

  • 初始标记(需要STW):

标记GC Root能够直接关联到的对象,该阶段需要短暂停顿,但是耗时很短

  • 并发标记

从GC Root开始对堆中的对象进行可达性分析,递归扫描整个堆里的对象图,找到要回收的对象,该阶段耗时比较长,可以与用户程序并发执行

  • 最终标记(需要STW)

对用户线程做一个短暂的暂停,用于处理并发阶段结束后仍遗留下来的最后那少量的SATB记录

  • 筛选回收(需要STW)

负责更新Region的统计数据,对各个Region的回收价值和成本进行排序,根据用户所期望的停顿时间来制定回收计划。然后把决定回收的那一部分的Region的存活对象复制到空的Region中,再清理掉整个旧的Region的全部空间。这里的操作涉及到存活对象的移动,是必须暂停用户线程的,由多条收集器线程并行完成的

优势:

  • 并行(多核CPU)与并发;
  • 分代收集(新生代和老年代区分不明显);
  • 空间整合,G1从整体上来看是基于“标记-整理”算法实现的,从局部两个region之间又是基于”标记-复制“算法实现。这两种算法都意味着G1运作期间不会产生内存碎片;
  • 限制收集范围,可预测的停顿。

缺点:

需要额外占用百分之十到百分之二十内存

搭配组合:

默认垃圾回收方式 代表垃圾回收器

默认垃圾回收方式代表垃圾回收器
UseSerialGC“Serial” + “Serial Old”
UseParNewGC“ParNew” + “Serial Old”
UseConcMarkSweepGC“ParNew” + “CMS”
UseParallelGC“Parallel Scavenge” + “Parallel Old”
UseParallelOldGC“Parallel Scavenge” + “Parallel Old”

JVM日志打印详情

# 必备
-XX:+PrintGCDetails 
# 打印对象分布情况
-XX:+PrintGCDateStamps 
-XX:+PrintTenuringDistribution 
# 每次发生GC后查看下堆前后的内存情况
-XX:+PrintHeapAtGC 
# 打印引用信息
-XX:+PrintReferenceGC 
# STW时间
-XX:+PrintGCApplicationStoppedTime# 可选
-XX:+PrintSafepointStatistics 
-XX:PrintSafepointStatisticsCount=1# GC日志输出的文件路径
-Xloggc:/path/to/gc-%t.log
# 开启日志文件分割
-XX:+UseGCLogFileRotation 
# 最多分割几个文件,超过之后从头文件开始写
-XX:NumberOfGCLogFiles=14
# 每个文件上限大小,超过就触发分割
-XX:GCLogFileSize=100M

http://www.ppmy.cn/news/51109.html

相关文章

多线程编程常用函数用法

一、多线程编程常用函数用法 1、pthread_create 头文件 #include<pthread.h>函数声明 int pthread_create(pthread_t*restrict tidp,const pthread_attr_t *restrict_attr,void*&#xff08;*start_rtn)(void*),void *restrict arg)函数功能 pthread_create是UNIX环境…

水果FL Studio21最新中文完整版下载更新及内容介绍

简单总结一下&#xff0c;本次小版本更新最重要的内容&#xff0c;我个人认为是对于M1芯片的适配。其余的比如EQ2&#xff0c;3x这些我们很熟悉的插件虽说也有更新&#xff0c;但是估计并没有特别大的改动。我个人的话会先放一段时间&#xff0c;等下次有其他更让我感兴趣的内容…

oracle 11g等保加固

有个单机环境需要做个等保加固 1、执行如下sql ?/rdbms/admin/utlpwdmg.sql --alter profile default limit password_verify_function null; Alter PROFILE DEFAULT LIMIT PASSWORD_LIFE_TIME 90; alter profile DEFAULT limit password_lock_time 30; alter profile DEFAU…

mysql_exporter在Linux上的安装与配置

mysqld_exporter 是一个用于监控 MySQL 数据库的 Prometheus exporter。可以从 MySQL 数据库的 metrics_schema 收集指标&#xff0c;相关指标主要包括: MySQL 服务器指标:例如 uptime、version 等数据库指标:例如 schema_name、table_rows 等表指标:例如 table_name、engine、…

看板与 Scrum:有什么区别?

看板和Scrum是项目管理方法论&#xff0c;以小增量完成项目任务并强调持续改进。但是他们用来实现这些目标的过程是不同的。看板以可视化任务和连续流程为中心&#xff0c;而Scrum更多是关于为每个交付周期实施时间表和分配设定角色。 在看板和Scrum之间做出选择并不总是必要…

Android Display架构分析,黑屏,系统架构

(642条消息) Android Display架构分析_lin-0410的博客-CSDN博客 (644条消息) Android系统架构_橙子19911016的博客-CSDN博客 1 Android 系统架构 Android 是谷歌开发的一款基于 Linux 内核的操作系统。系统架构分为五层&#xff0c;从下到上依次是Linux内核层、硬件抽象层、系…

P1040 [NOIP2003 提高组] 加分二叉树

题目描述 设一个 &#xfffd;n 个节点的二叉树 treetree 的中序遍历为(1,2,3,…,&#xfffd;)(1,2,3,…,n)&#xff0c;其中数字 1,2,3,…,&#xfffd;1,2,3,…,n 为节点编号。每个节点都有一个分数&#xff08;均为正整数&#xff09;&#xff0c;记第 &#xfffd;i 个节…

ch6_1计算机中运算方法

计算机中数的表示计算机的运算方法运算器的设计 参考教材 本章内容主要介绍&#xff0c;计算机中的运算方法 无符号数和有符号数数的定点表示和浮点表示定点运算浮点四则运算算术逻辑单元 1. 无符号数和有符号数 1.1 无符号数 1.2 有符号数 计算机中&#xff0c; 小数点…