JVM垃圾回收-7种垃圾收集器

2024-05-25 07:48
文章标签 java jvm 回收 收集器 垃圾

本文主要是介绍JVM垃圾回收-7种垃圾收集器,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.概述

垃圾收集器是垃圾回收算法(标记-清除算法、复制算法、标记-整理算法)的具体实现,不同商家、不同版本的JVM所提供的垃圾收集器可能会有很在差别,本文主要介绍HotSpot虚拟机中的垃圾收集器。7种垃圾收集器如图所示。
图中表示7种作用于不同分代的收集器,如果两个收集器之间存在连线,说明可以搭配使用。横线上办部分为年轻代的垃圾收集器,下半部分为老年代的垃圾收集器。

2.相关概念

2.1STW机制

Stop-The-World机制简称STW,是在执行垃圾收集算法时,Java应用程序的其他所有线程都被挂起(除了垃圾收集帮助器之外)。Java中一种全局暂停现象,全局停顿,所有Java代码停止,native代码可以执行,但不能与JVM交互;这些现象多半是由于gc引起。

2.2吞吐量

指的是CPU用于运行用户代码的时间与CPU总消耗时间的比值,即
吞吐量 = 运行用户代码时间 /(运行用户代码时间 + 垃圾收集时间)。
假设虚拟机总共运行了100分钟,其中垃圾收集花掉1分钟,那吞吐量就是99%。

2.3并行和并发

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

2.4Minor GC 和 Full GC

  • 新生代GC(Minor GC):指发生在新生代的垃圾收集动作,因为Java对象大多都具备朝生夕灭的特性,所以Minor GC非常频繁,一般回收速度也比较快。
  • 老年代GC(Major GC / Full GC):指发生在老年代的GC,出现了Major GC,经常会伴随至少一次的Minor GC(但非绝对的,在Parallel Scavenge收集器的收集策略里就有直接进行Major GC的策略选择过程)。Major GC的速度一般会比Minor GC慢10倍以上。

3.Serial收集器

收集器流程图如图所示

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


特点:单线程的收集器,在工作时,必须暂停其他所有的工作线程,直至它收集结束。也是虚拟机默认的新生代收集器
优点:

  • 单线程执行,没有线程交互的开销,
  • 垃圾收集停顿在几百毫秒内,这一定程度上可以接受

缺点:STW问题(“Stop The World”)

4.ParNew收集器

ParNew收集器就是Serial收集器多线程的版本。 除了多线程外,其余的行为、特点和Serial收集器一样;
在Server模式下,ParNew收集器是一个非常重要的收集器,因为除Serial外,目前只有它能与CMS收集器配合工作;
但在单个或两个CPU环境中,不会比Serail收集器有更好的效果,因为存在线程交互开销。

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

设置参数

  • "-XX:+UseConcMarkSweepGC":指定使用CMS后,会默认使用ParNew作为新生代收集器;
  • "-XX:+UseParNewGC":强制指定使用ParNew;
  • "-XX:ParallelGCThreads":指定垃圾收集的线程数量,ParNew默认开启的收集线程与CPU的数量相同;

5.parallel scavenger收集器

parallel scavenger收集器是达到一个可控制吞吐量。既尽量的缩短垃圾收集时间,保证与用户的交互速度。既给定一个指定的垃圾收集停顿收集,当垃圾收集时间超过给定值,无论是否回收完成都会停止回收工作。

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

特点:

  • 新生代收集器
  • 与ParNew一样 并行的多线程收集器

设置参数

  • -XX:MaxGCPauseMillis
    控制最大垃圾收集停顿时间,大于0的毫秒数
    MaxGCPauseMillis设置得稍小,停顿时间可能会缩短,但也可能会使得吞吐量下降。因为可能导致垃圾收集发生得更频繁
  • -XX:GCTimeRatio
    设置垃圾收集时间占总时间的比率,0<n<100的整数
    GCTimeRatio相当于设置吞吐量大小
  • -XX:+UseAdptiveSizePolicy
    这是一个开关参数,打开参数后,就不需要手工指定新生代的大小(-Xmn)、Eden和Survivor区的比例(-XX:SurvivorRatio)、晋升老年代对象年龄(-XX:PretenureSizeThreshold)等细节参数了,虚拟机会根据当前系统的运行情况收集性能监控信息,动态调整这些参数以提供最合适的停顿时间或者最大的吞吐量,这种方式称为GC自适应的调节策略(GC Ergonomics)。自适应调节策略也是Parallel Scavenge收集器与ParNew收集器的一个重要区别。

6.Serial Old收集器

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

Serial Old 是 Serial收集器的老年代版本,它同样是一个单线程收集器,使用 “标记-整理”(Mark-Compact) 算法。
此收集器的主要意义也是在于给Client模式下的虚拟机使用。如果在Server模式下,它还有两大用途:

  • 在JDK1.5 以及之前版本(Parallel Old诞生以前)中与Parallel Scavenge收集器搭配使用
  • 作为CMS收集器的后备预案,在并发收集发生Concurrent Mode Failure时使用

7.Parallel Old收集器

Parallel Old收集器是parallel scavenger收集器的老年代版本。

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

  • 采用“标记-整理”算法
  • 多线程执行
  • Parallel Old收集器的工作流程与Parallel Scavenge相同

8.CMS收集器

CMS收集器是一种以获取最短回收停顿时间为目标的收集器。CMS收集器基于“标记-清除”算法。它分为4个步骤

  • 初始标记(会产生STW机制,标记一下GC Roots能直接关联到的对象)
  • 并发标记(进行GC RootsTracing的过程)
  • 重新标记(会产生STW机制,为了修正并发标记期间因用户程序继续运行而导致标记产生变动的那一部分对象的标记记录)
  • 并发清除
    其中耗时最长的并发标记和并发清除过程可以与用户线程一起工作。执行过程如图所示

优点:发收集、低停顿,因此CMS收集器也被称为并发低停顿收集器(Concurrent Low Pause Collector)

缺点

  • 并发收集虽然不会暂停用户线程,但因为占用一部分CPU资源,还是会导致应用程序变慢,总吞吐量降低。
    CMS的默认收集线程数量是=(CPU数量+3)/4;
    当CPU数量多于4个,收集线程占用的CPU资源多于25%,对用户程序影响可能较大;不足4个时,影响更大,可能无法接受。。
  • 产生浮动垃圾
    在并发清除时,用户线程新产生的垃圾,称为浮动垃圾;这使得并发清除时需要预留一定的内存空间,不能像其他收集器在老年代几乎填满再进行收集;也要可以认为CMS所需要的空间比其他垃圾收集器大;
    "-XX:CMSInitiatingOccupancyFraction":设置CMS预留内存空间;
    JDK1.5默认值为68%;
    JDK1.6变为大约92%;
  • 标记-清除算法导致产生大量内存碎片
    产生大量不连续的内存碎片会导致分配大内存对象时,无法找到足够的连续内存,从而需要提前触发另一次Full GC动作。
    解决方法:
  • "-XX:+UseCMSCompactAtFullCollection"
    使得CMS出现上面这种情况时不进行Full GC,而开启内存碎片的合并整理过程;
    但合并整理过程无法并发,停顿时间会变长;
    默认开启(但不会进行,结合下面的CMSFullGCsBeforeCompaction);
  • "-XX:+CMSFullGCsBeforeCompaction"
    设置执行多少次不压缩的Full GC后,来一次压缩整理;
    为减少合并整理过程的停顿时间;
    默认为0,也就是说每次都执行Full GC,不会进行压缩整理;

9.G1收集器

G1收集器运行示意图

特点:
并行与并发:

  • 能充分利用多CPU、多核环境下的硬件优势
  • 可以并行来缩短"Stop The World"停顿时间
  • 也可以并发让垃圾收集与用户程序同时进行

分代收集:

  • 不需要搭配其他收集器进行配合使用
  • 采用不同的方式处理不同的对象

空间整合,不产生碎片

  • 从整体看,是基于标记-整理算法
  • 从局部(两个Region间)看,是基于复制算法
  • 可预测的停顿:低停顿的同时实现高吞吐量

10.总结

收集器串行、并行or并发新生代/老年代算法目标适用场景
Serial串行新生代复制算法响应速度优先单CPU环境下的Client模式
Serial Old串行老年代标记-整理响应速度优先单CPU环境下的Client模式、CMS的后备预案
ParNew并行新生代复制算法响应速度优先多CPU环境时在Server模式下与CMS配合
Parallel Scavenge并行新生代复制算法吞吐量优先在后台运算而不需要太多交互的任务
Parallel Old并行老年代标记-整理吞吐量优先在后台运算而不需要太多交互的任务
CMS并发老年代标记-清除响应速度优先集中在互联网站或B/S系统服务端上的Java应用
G1并发both标记-整理+复制算法响应速度优先面向服务端应用,将来替换CMS

这篇关于JVM垃圾回收-7种垃圾收集器的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1000897

相关文章

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

Spring Security--Architecture Overview

1 核心组件 这一节主要介绍一些在Spring Security中常见且核心的Java类,它们之间的依赖,构建起了整个框架。想要理解整个架构,最起码得对这些类眼熟。 1.1 SecurityContextHolder SecurityContextHolder用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

Java进阶13讲__第12讲_1/2

多线程、线程池 1.  线程概念 1.1  什么是线程 1.2  线程的好处 2.   创建线程的三种方式 注意事项 2.1  继承Thread类 2.1.1 认识  2.1.2  编码实现  package cn.hdc.oop10.Thread;import org.slf4j.Logger;import org.slf4j.LoggerFactory

离心萃取机废旧磷酸铁锂电池回收工艺流程

在废旧磷酸铁锂电池的回收工艺流程中,离心萃取机主要应用于萃取除杂的步骤,以提高回收过程中有价金属(如锂)的纯度。以下是结合离心萃取机应用的废旧磷酸铁锂电池回收工艺流程: 电池拆解与预处理 拆解:将废旧磷酸铁锂电池进行拆解,分离出电池壳、正负极片、隔膜等部分。破碎与筛分:将正负极片进行破碎处理,并通过筛分将不同粒径的物料分开,以便后续处理。 浸出与溶解 浸出:采用适当的浸出工艺(如二段式逆

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听