前言

垃圾收集算法是内存回收的方法论;垃圾收集器是内存回收的具体实现。Java虚拟机规范中对垃圾收集器应该如何实现并没有任何规定,因此不同的厂商、不同版本的虚拟机所提供的垃圾收集器都有很大的差别,并且一般都会提供参数供用户根据自己的应用特点和要求组合出各个年代所使用的收集器。
 
虚拟机里并不是使用一个收集器,而是很多收集器搭配使用,在不同的年代使用不同的收集器。

一、Serial收集器

Serial收集器是最基本、发展历史最悠久的收集器、曾经是虚拟机新生代收集的唯一选择。这个收集器是一个单线程的收集器,但它的“单线程”的意义并不仅仅说明它只会使用一个CPU或一条收集线程去完成垃圾收集工作,更重要的是在他进行垃圾收集时,必须暂停其他所有的工作线程,直到他收集结束。“Stop-The-World”这项工作实际是是由虚拟机在后台自动发起和自动完成的,在用户不可见的情况下把用户正常工作的线程全部停掉,这是比较难以接受的。
 

 

二、ParNew收集器

ParNew收集器就是Serial收集器的多线程版本,处理使用多条线程进行垃圾收集之外,其余行为包括Serail收集器可用的所有控制参数(例如:-XX:SurvivorRatio、-XX:PretenureSizeThreshold、-XX:HandlePromotionFailure等)、收集算法、Stop the World、对象分配规则、回收策略等都与Serail收集器完全一致,在实现上,两者也共用了很多代码。

ParNew收集器除了多线程收集之外,其他与Serial收集器相比并没有多大的创新之处,但它却是许多运行在Server模式下的虚拟机中首选的新生代收集器,其中有一个与性能无关但很重要的原因是,除了Serial收集器外,目前只有它能与CMS收集器配合工作。
 

三、Paraller Scanvenge收集器

Paraller Scanvenge收集器是一个新生代收集器,它也是使用复制算法的收集器,又是并行的多线程收集器。
 
Paraller Scanvenge收集器的特点是它的关注点与其他收集器不同,CMS等收集器的关注点是尽可能的缩短垃圾收集器收集时用户现程的停顿时间,而Paraller Scavenge收集器的目标这是达到一个可控制的吞吐量(Throughput)。所谓吞吐量就是CPU用于运行用户代码的时间与CPU总消耗时间的比值。即吞吐量=运行用户代码时间/(运行用户代码时间 + 垃圾收集时间)。
 
停顿时间越短越适合需要与用户交互的程序,良好的响应速度能提升用户体验,而高吞吐量则可以高效率的利用CPU时间,尽快的完成程序的运算任务,主要适合在后台运算而不需要太多交互的任务。
 
parallel Scavenge收集器提供了两个参数用于精确控制吞吐量,分别是控制最大垃圾收集器停顿时间的-XX:MaxGCPauseMillis参数以及直接设置吞吐量大小的-XX:GCTimeRatio参数。
 
MaxGCPauseMillis 参数允许的值是一个大于0的毫秒数,收集器将尽可能地保证内存回收花费的时间不超过设定值。
GCTimeRatio参数的值应当是一个大于0且小于100的整数,也就是垃圾收集时间占比总时间的比率。
 
注:

并行(Paraller):指多条来及收集线程并行工作,但此用户线程仍然处于等待状态
并发(Concurrent):值用户线程与垃圾收集线程同时执行(但不一定是并行的,可能会交替执行),用户程序在继续运行,而垃圾收集程序运行在另一个CPU上。
 

4、Serial Old收集器

Serial Old 收集器是Serial 收集器的老年代版本,它同样是一个单线程收集器,使用“标记-整理”算法。这个收集器的主要意义也是在与Client模式下的虚拟机使用。如果在Server模式下,那么他还有两大用途,一是在JDK1.5以及之前的版本中与Paraller Scavenge收集器搭配使用,另一种用途是做为CMS收集器的后备预案,在并发收集发生Concurrent Mode Failure时使用。
 

五、parallel Old 收集器

Paraller Old收集器是Paraller Scavenge收集器的老年代版本,使用多线程和“标记-整理”算法。

6、CMS收集器

 
CMS(Concurrent Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器。CMS收集器是基于“标记-清除”算法实现的,它的运作过程分为4个步骤:
 
1)初始标记(CMS initial mark)
2)并发标记(CMS concurrent mark)
3)重新标记(CMS remark)
4)并发清除(CMS concurrent sweep)
 
其中,初始标记和重新标记这两个步骤仍然需要“Stop the World”(停止工作线程)。初始标记仅仅只是标记一下GC Roots能直接关联到的对象,速度很快。并发标记阶段就是进行GC Roots Tracing的过程,而重新标记阶段则是为了修正并发标记期间因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录,这个阶段的停顿时间一般会比初始标记阶段稍长一些,但远比并发标记的时间短。
 

 

七、G1(Garbage-First)收集器

G1(Garbage-First)收集器是一款面向服务端应用的垃圾收集器。如果不计算维护Remembered Set的操作,G1收集器的运作大致可以分为以下几个步骤:
1)初始标记(Initial Marking)
2)并发标记(Concurrent Marking)
3)最终标记(Final Marking)
4)筛选回收(Live Data Counting and Evacuation)
 

 
 

想买保时捷的运维李先生学Java性能之 垃圾收集器的更多相关文章

  1. 想买保时捷的运维李先生学Java性能之 垃圾收集算法

    前言 从原来只知道-Xms.-Xmx是设置内存的,到现在稍微理解了一些堆内存等Java虚拟机的一些知识.明白了技术这一个东西还是得要有输入才能实践,原理与实践要相辅相成,后续把JVM的监控好好总结一下 ...

  2. 想买保时捷的运维李先生学Java性能之 运行时数据区域

    前言 不知道自己不知道,不知道自己知道,知道自己不知道,知道自己知道,目前处于知道自己不知道这个阶段,很痛苦啊,干了4年了运维,是一个坎.越来越发觉想要走得远,还是得扎根底.   一.运行时数据区域 ...

  3. 想买保时捷的运维李先生学Java性能之 生存与毁灭

    一.判断对象是否存活     1.引用计数算法   给对象中添加一个引用计数器,每当有一个地方引用它时,计数器就加1:当引用失效时,计数器的值就减1:任何时刻计数器为0的对象是不可能再被使用的.引用计 ...

  4. 想买保时捷的运维李先生学Java性能之 JIT即时编译器

    前言 本文记录日常学习<深入理解Java虚拟机>,不知道为啥感觉看一遍也就过了,喜欢动动手理解理解,这样才有点感觉,静不下心来的时候,看书抄书也可以用这个办法. 一.什么是JIT(Just ...

  5. Linux运维不可不知的性能监控和调试工具

    Linux运维不可不知的性能监控和调试工具 1 nagios Nagios是一个开源监控解决方案,我觉得他可以监控一切 ,可以看一下我以前的文章:NAGIOS 2 ps #用来查看程序的运行情况 ps ...

  6. Python_oldboy_自动化运维之路_函数,装饰器,模块,包(六)

    本节内容 上节内容回顾(函数) 装饰器 模块 包 1.上节内容回顾(函数) 函数 1.为什么要用函数? 使用函数之模块化程序设计,定义一个函数就相当于定义了一个工具,需要用的话直接拿过来调用.不使用模 ...

  7. 从零开始学 Java - Spring AOP 拦截器的基本实现

    一个程序猿在梦中解决的 Bug 没有人是不做梦的,在所有梦的排行中,白日梦最令人伤感.不知道身为程序猿的大家,有没有睡了一觉,然后在梦中把睡之前代码中怎么也搞不定的 Bug 给解决的经历?反正我是有过 ...

  8. 从零起步做到Linux运维经理, 你必须管好的23个细节

    “不想成为将军的士兵,不是好士兵”-拿破仑 如何成为运维经理? 一般来说,运维经理大概有两种出身:一种是从底层最基础的维护做起,通过出色的维护工作,让公司领导对这个人非常认可,同时对Linux运维工作 ...

  9. 从零起步做到Linux运维经理,你必须管好的23个细节

    不想成为将军的士兵,不是好士兵-拿破仑 如何成为运维经理?成为运维经理需要什么样的能力?我想很多运维工程师都会有这样的思考和问题. 如何成为运维经理.一般来说,运维经理大概有两种出身,一种是从底层最基 ...

随机推荐

  1. Oracle添加键值对盲注

    前言 遇到一种注入点,存在于POST参数中,却不能用sqlmap扫出: 分析 request参数格式: %24Q_value1=test1&orderCol=&order=+ASC+& ...

  2. spring:spring再总结(ioc、aop、DI等)

    IOC(Inversion of Control),即"控制反转",不是一种技术而是一种思想 1.IOC的理解 Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部 ...

  3. Python-变量-数字类型

    数字 number 整形 int 浮点型 float bool True(=1) False(=0) int_num = 10 float_num = 10.1 bool_True = True bo ...

  4. .NET 是信息技术应用创新产业重要参与者

    今天是国庆节,也是中秋节,月满中秋,举国欢庆,在这里祝各位开发者中秋国庆快乐. 放假在家就想把这几年对于.NET发展相关生态做个梳理,写一篇文章来总结一下这两年从腾讯出来自己创业,推动.NET在国内的 ...

  5. Python练习题 044:Project Euler 016:乘方结果各个数值之和

    本题来自 Project Euler 第16题:https://projecteuler.net/problem=16 ''' Project Euler 16: Power digit sum 2* ...

  6. [WC 2011]最大Xor和路径

    题目大意: 给你一张n个点,m条边的无向图,每条边都有一个权值,求:1到n的路径权值和的最大值. 题解: 任意一条路径都能够由一条简单路径(任意一条),在接上若干个环构成(如果不与这条简单路径相连就走 ...

  7. Consul 快速入门

    Consul是什么 Consul是一个服务网格(微服务间的 TCP/IP,负责服务之间的网络调用.限流.熔断和监控)解决方案,它是一个一个分布式的,高度可用的系统,而且开发使用都很简便.它提供了一个功 ...

  8. Fabric1.4.4 多机solo共识搭建

    简单记录一下fabric版本1.4.4的搭建部署,运行环境为CentOs7.8,如有错误欢迎批评指正.然后就是本编文章不对环境搭建做说明,基础环境搭建看这里. 1.总体设计 本案例部署一个排序(ord ...

  9. 架构师根本不会被语言限制住,php照样可以用领域驱动设计DDD四层架构!

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 你在通往架构师的路上吗? 程序员这个行业就像是在不断的打怪升级,突破每一阶段的瓶颈期 ...

  10. DX12龙书 02 - DirectXMath 库中与向量有关的类和函数

    0x00 需要用到的头文件 #include <DirectXMath> #include <DirectXPackedVector.h> using namespace Di ...