深入理解Java虚拟机:Java垃圾回收器

本篇内容包括:7 种 Jvm 垃圾回收器的介绍、对比 以及 对应的 Jvm 参数设置,这 7 种包括了:Serial、ParNew 以及 Parallel Scavenge 三种新生代回收器 和 :Serial Old、Parallel Old 以及 CMS 三种老年代回收器,此外还有一个 G1 回收器是 Java 目前比较前沿的成果…

一、Jvm 垃圾回收器概述

我们前面提到了,垃圾回收器的 回收的内容、回收的时机以及回收的方式,接下来我们来看 Java 垃圾回收器。如果垃圾回收算法是内存回收的方法论的话,那么垃圾回收器就是内存回收的具体实现了。

Jvm 的垃圾回收器根据场景和实现方式可以分为新生代回收器和老年代回收器,新生代回收器与老年代回收器可以搭配使用。

  • 新生代回收器包括:Serial、ParNew 以及 Parallel Scavenge;
  • 老年代回收器包括:Serial Old、Parallel Old 以及 CMS;
  • 此外,Java7 update 4(第七版第四个更新升级包)之后引入了一个 G1 收集器。

Ps:不同垃圾回收器适合于不同的内存区域,有的两个垃圾回收器之间也可以配合使用!

在这里插入图片描述


二、新生代回收器

1、Serial 收集器

Serial 收集器是最基础且历史最悠久的垃圾收集器,作为单线程工作的收集器。Serial 会在它工作时要求暂停用户所有的其他线程(Stop-the-World 机制)。采用的是 “标记-复制” 算法。垃圾清理时,Serial 回收器不存在线程间的切换,因此,在单 CPU 的环境下,垃圾清除效率比较高。

Serial / Serial Old收集器运行示意图

虽然 Serial 收集器是最基础最老的收集器,但是迄今为止 HotSpot 虚拟机运行在 Client 模式下的默认的新生代垃圾收集器!相较于其他收集器,Serial 具有以下 3 个优点:

  1. 简单高效;
  2. 所有收集器中额外内存消耗最少;
  3. 针对内存几十兆或一两百兆的新生代,停顿时间能控制在一百毫秒内。

Ps:这里需要注意的一点是 Serial 收集器和 Serial Old 收集器在垃圾收集时不是单线程的,通常所描述的"单线程"是指的垃圾回收时暂停其他所有的工作线程。

2、ParNew 收集器

ParNew 收集器大致可以理解为是 Serial 收集器的多线程版本,因为 ParNew 收集器除了采用并行回收的方式执行内存回收外,与 Serial 收集器之间几乎没有任何区别。ParNew 收集器在年轻代中同样也是采用复制算法、Stop-the-World 机制。

ParNew /Serial Old收集器运行示意图

ParNew 收集器是很多版本 Jvm(包括 HotSpot)运行在 Server 模式下新生代的默认垃圾收集器。

ParNew 收集器运行在多 CPU 的环境下,由于可以充分利用多 CPU、多核心等物理硬件资源优势,可以更快的完成垃圾收集,提升程序的吞吐量。但是在单个 CPU 的环境下,ParNew 收集器不比 Serial 收集器更高效,虽然 Serial 收集器是基于串行回收,但是由于 CPU不需要频繁的切换,因此可以有效避免多线程交互过程中产生的一些额外开销。

Ps:除了 Serial 外,目前只有 ParNew GC 能与 CMS 收集器配合工作。

3、Parallel Scavenge 收集器

Parallel Scavenge 收集器同 ParNew 收集器一样,也是采用 “标记-复制” 算法,且为能够并行收集的多线程收集器。

Parallel Scavenge 的特点是其关注重点为吞吐量,高吞吐量则可以高效率地利用 CPU 时间,尽快完成程序的运算,但也就是说它的线程单次停止时间可能更长,因此适用于后台计算型任务程序:Parallel Scavenge /Parallel Old收集器运行示意图

Ps:如果虚拟机完成某个任务,用户代码加上垃圾收集总共耗费了 100 分钟,其中垃圾收集花掉 1 分 钟,那吞吐量就是 99% :
吞吐量=运行用户代码时间/运行用户代码时间+运行垃圾回收时间吞吐量=运行用户代码时间/运行用户代码时间+运行垃圾回收时间 吞吐量=运行用户代码时间/运行用户代码时间+运行垃圾回收时间


三、老年代回收器

1、Serial Old 收集器

Serial Old 是 Serial 收集器的老年代版本,采用“标记-整理”算法,单线程收集器,也是给 Client 模式下的虚拟机使用。

Serial / Serial Old收集器运行示意图

Ps:在 Jdk1.5 及其以前,它常与 Parallel Scavenge 回收器配合使用,达到较好的吞吐量,另外它也是 CMS 回收器在 Concurrent Mode Failure 时的后备方案。

2、Parallel Old 收集器

Parallel Old 回收器是 Parallel Scavenge 回收器的老生代版本,属于多线程回收器,采用“标记-整理”算法。Parallel Old 回收器和 Parallel Scavenge 回收器同样考虑了吞吐量优先这一指标,非常适合那些注重吞吐量和 CPU 资源敏感的场合。

Parallel Scavenge /Parallel Old收集器运行示意图

Ps:在注重吞吐量以及 CPU 资源敏感的场合,可以优先考虑 Parallel Scavenge 加 Parallel Old 收集器

3、CMS 收集器

CMS 收集器,是一种以获取最短回收停顿时间为目标的收集器,其缩写含义为 Concurrent Mark Sweep,Mark Sweep 指的是“标记-清除”算法,在互联网网站、B/S 架构的中常用的收集器就是 CMS,因为系统停顿的时间最短,给用户带来较好的体验。

CMS 收集器运行示意图

CMS收集器的运作过程分为4个步骤,包括:

  • 初始标记(短暂),仅仅只是标记一下 GCRoots 能直接关联到的对象,速度很快;
  • 并发标记(和用户的应用程序同时进行),进行 GCRoots 追踪的过程,标记从 GCRoots 开始关联的所有对象开始遍历整个可达分析路径的对象。这个时间比较长,所以采用并发处理(垃圾回收器线程和用户线程同时工作);
  • 重新标记(短暂),为了修正并发标记期间因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录,这个阶段的停顿时间一般会比初始标记阶段稍长一些,但远比并发标记的时间短;
  • 并发清除(和用户的应用程序同时进行):垃圾回收

整个过程中耗时最长的并发标记和并发清除过程收集器线程都可以与用户线程一起工作,所以,从总体上来说,CMS 收集器的内存回收过程是与用户线程一起并发执行的。


四、G1 收集器

G1(Garbage-First)收集器是最前沿的成果之一,在Java7 update 4之后引入(Jdk7 的第 4 个版本),是一款面向服务端应用的垃圾收集器。在多 CPU 和大内存的场景下有很好的性能。HotSpot 开发团队赋予它的使命是未来可以替换掉 CMS 收集器。

G1 是一个分代的,增量的,并行与并发的“标记-复制”垃圾回收器。它的设计目标是为了适应现在不断扩大的内存和不断增加的处理器数量,进一步降低暂停时间(pause time),同时兼顾良好的吞吐量。

G1收集器的优势:

  • 独特的分代垃圾回收器,分代GC: 分代收集器,同时兼顾年轻代和老年代;

  • 使用分区算法,不要求 eden,年轻代或老年代的空间都连续;

  • 并行性: 回收期间,可由多个线程同时工作,有效利用多核cpu资源;

  • 空间整理: 回收过程中,会进行适当对象移动,减少空间碎片;

  • 可预见性: G1 可选取部分区域进行回收,可以缩小回收范围,减少全局停顿。

G1 收集器运行示意图

G1收集器的阶段分以下几个步骤:

  1. 初始标记(它标记了从GC Root开始直接可达的对象);

  2. 并发标记(从GC Roots开始对堆中对象进行可达性分析,找出存活对象);

  3. 最终标记(标记那些在并发标记阶段发生变化的对象,将被回收);

  4. 筛选回收(首先对各个Regin的回收价值和成本进行排序,根据用户所期待的GC停顿时间指定回收计划,回收一部分Region)。


五、相关知识点

1、HotSpot 的 Server 和 Client 两种模式

HotSpot 包括 Server 和 Client 两种模式的实现:

  • Java HotSpot Client VM(-client),为在客户端环境中减少启动时间而优化;
  • Java HotSpot Server VM(-server),为在服务器环境中最大化程序执行速度而设计。

比较:Server VM 启动比 Client VM 慢,运行比 Client VM 快。Server 模式的运行中,垃圾回收处理做的比较好一些。

2、设置回收器的参数

下面给出配置回收器时,经常使用的参数:

  • -XX:+UseSerialGC:在新生代和老年代使用串行收集器
  • -XX:+UseParNewGC:在新生代使用并行收集器
  • -XX:+UseParallelGC :新生代使用并行回收收集器,更加关注吞吐量
  • -XX:+UseParallelOldGC:老年代使用并行回收收集器
  • -XX:ParallelGCThreads:设置用于垃圾回收的线程数
  • -XX:+UseConcMarkSweepGC:新生代使用并行收集器,老年代使用CMS+串行收集器
  • -XX:ParallelCMSThreads:设定CMS的线程数量
  • -XX:+UseG1GC:启用G1垃圾回收器

3、各类回收器总结

回收器回收代回收模式回收算法特点
Serial新生代单线程标记-复制简单高效,内存消耗少, 停顿时间能控制在一百毫秒内
ParNew新生代多线程标记-复制Serial 的多线程版本
Parallel Scavenge新生代多线程标记-复制关注重点为吞吐量
Serial Old老年代单线程标记-整理同 Serial 简单高效,内存消耗少
Parallel Old老年代多线程标记-整理同 Parallel Scavenge 适合那些注重吞吐量和 CPU 资源敏感的场合
CMS老年代多线程标记-清除并发收集、低停顿,但是会产生大量空间碎片、并发阶段会降低吞吐量
G1多线程标记-复制同时兼顾年轻代和老年代,针对于大 heap

垃圾回收器的选用决定因素:应用程序的场景、硬件的制约 以及 吞吐量的需求。

  • 串行垃圾回收是最简单的也是效率最低的,如果只是控制台的单线程程序,简单任务,并且机器配置不高,推荐使用。
  • 并行垃圾回收器是 64bit server 默认的垃圾回收器,一般我们工作和生产上默认不配置,都是并行垃圾回收。对于一般的不要求吞吐的应用,并且硬件资源不是太充足的情况下,并行垃圾回收器差不多能满足需求。
  • CMS 垃圾回收器是对并行垃圾回收器的一个优化,它以 CPU 和系统资源为代价,换取 GC 的延迟。不会一 GC 就 STW,而是根据情况 STW。一定程度上是资源换取速度。
  • G1 垃圾回收器是针对于大 heap 的垃圾回收器,如果 heap 分配的足够大,分的 region 的优先级回收策略会优先清理垃圾多的 region 并且减少了内存空间碎片,分配大对象时不会因为无法找到连续内存空间而提前触发下一次 GC。

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

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

相关文章

oracle跨越千年处理

如果指定的两位年份0-4950-99 如果当前 的两位年 份是 0-49返回的日期是当前世纪返回的日期是上个世纪50-99返回的日期是下个世纪返回的日期是当前世纪 current yearSpecified DateRR FormatYY Format199527-OCT-9519951995199527-OCT-171951917200127-OCT-1720012017200127-OC…

网络协议:什么是网络分层的七四五

本篇内容包括:网络分层七层、五层、四层网络协议概念的介绍,IOS 体系结构的介绍与构成、TCP/IP体系结构的简介及与IOS体系的关系 以及五层体系结构的介绍。 一、七层、五层、四层网络协议概念 1、关于网络协议 网络协议,即是指计算机网络中…

查看表空间相关命令

默认表空间数据文件大小根据DATA BLOCKS的大小有关,默认最大为32GB表空间达到32G,只能增加数据文件alter tablespace 表空间名 add datafile 数据文件路径‘ size 500m autoextend on next 100m maxsize 10000M;未达到32G,修改数据文件的扩展…

网络协议:一文搞懂Socket套接字

本篇内容包括:Socket 套接字的简介、Socket 套接字的分类、Java 中的 Socket 即 java.net.ServerSocket、java.net.Socket 的使用,以及Java 使用套接字 Scoket 编程的Demo。 一、Socket 简介 TCP(传输控制协议)是一种面向连接的、…

RESETLOGS

使用resetlogs选项,会把当前的日志序号(log sequence number)重设为1,并抛弃所有日志信息。在以下条件时需要使用resetlogs选项: 在不完全恢复(介质恢复); 使用备份控制文件。 使…

网络协议:透彻解析HTTP协议

本篇内容包括:HTTP 协议定义及其特点概述、关于 URL 定义及分类概述、Request 请求、Response 响应 以及 浏览器访问一个网站的全过程 等内容… 一、HTTP 协议概述 HTTP(HyperText Transfer Protocol) 即 超文本传输协议,它是一种…

oracle参数文件和口令文件

外部 审核 口令:记录超级用户的用户名和口令,做sys用户的安全审核 oracle9以后全部使用sys登录,但需要使用as sysdba ,之前版本需要使用internal o7字典打开 只要用户和密码存在于口令文件,就可以以sysdba登录&#…

innobackup备份恢复实操步骤--gtid复制(1)(1)

首先在主库进行备份: 备份命令: Innobackupex --defaults-file/app/dbcluster/sgrdb/mysql/my19103.cnf --no-timestamp --userdbscale --passwordS6000dbscale --host10.157.43.224 --port19103 /data/backup 如果使用setsid: setsid …

Redis系列:Redis的概述与安装

Redis(Remote Dictionary Server) 是一个使用 C 语言编写的,开源的(BSD许可)高性能非关系型(NoSQL)的键值对数据库。 本篇内容包括:Redis 简介(为什么快?为什么单线程?优…

安装LibreOffice和字体

#/bin/bash # Check if user is root if [ $(id -u) ! "0" ]; thenecho "Error: You must be root to run this script, please use root"exit 1 fi echo 安装LibreOffice cd /home/ tar -zxvf LibreOffice_6.3.3_Linux_x86-64_rpm.tar.gz cd /home/LibreO…

xtrabackup备份脚本

#!/bin/sh #备份主机 remote_ip100.0.132.160 Master_ip100.20.132.158 VIP100.20.132.166 #备份用户 userroot #密码 password00000 # 返回年月日 backup_datedate %F # 返回时分秒 backup_timedate %H-%M-%S # 返回今天是这周的第几天 backup_week_daydate %u backup_ok0 #备…

Redis系列:使用Redis实现分布式锁及相关问题

分布式锁其实就是,控制分布式系统不同进程共同访问共享资源的一种锁的实现。如果不同的系统或同一个系统的不同主机之间共享了某个临界资源,往往需要互斥来防止彼此干扰,以保证一致性。 本篇内容包括:关于 Redis 与 分布式锁&…

Redis系列:Redis持久化机制与Redis事务

Redis 是个基于内存的数据库。那服务一旦宕机,内存中数据必将全部丢失。所以丢失数据的恢复对于 Redis 是十分重要的,我们首先想到是可以从数据库中恢复,但是在由 Redis 宕机时(说明相关工作正在运行)且数据量很大情况…

Java基础:Java程序设计环境

按应用范围,Java 可分为 3 个体系,即 Java SE、Java EE 和 Java ME。Java 语言的开发运行,也离不开 Java 语言的运行环境 JRE。没有 JRE 的支持,Java 语言便无法运行。当然,如果还想编译 Java 程序,搞搞小开…

负载均衡策略

轮循均衡(Round Robin):每一次来自网络的请求轮流分配给内部中的服务器,从1至N然后重新开始。此种均衡算法适合于服务器组中的所有服务器都有相同的软硬件配置并且平均服务请求相对均衡的情况。 我们的业务web服务器都是同样配置…

Java基础:Java数据类型

Java 是一种强类型语言,这就意味着必须为每一个变量声明一种类型。在 Java 中基本数据类型共有 8 种,包括 4 种整型、2 种浮点型、1 种用于表现 Unicode 编码的字符单元的字符类型 char 和一种用于表示真值的 boolean 类型 ~ 本篇主要记录内容包括&#…

TCP连接的建立与终止

TCP连接的建立与终止 1.三次握手 TCP是面向连接的,无论哪一方向另一方发送数据之前,都必须先在双方之间建立一条连接。在TCP/IP协议中,TCP协议提供可靠的连接服务,连接是通过三次握手进行初始化的。三次握手的目的是同步连接双方…

日常问题:MySQL排序字段数据相同不能分页问题

【问题日期】 2022-11-14 22:45:12 【问题描述】 MySQL 排序字段数据相同不能分页问题:在分页查询数据时,按创建时间排序,由于数据是批量创建的,导致部分数据创建时间一样,而此时分页查询数据,翻页后出现…

数据缺失值处理

数据缺失值处理 In [1]: import pandas as pd import numpy as np from sklearn.ensemble import RandomForestRegressor,RandomForestClassifier from sklearn.preprocessing import StandardScaler from sklearn.impute import SimpleImputer In [2]: df pd.DataFrame() df[…