前言

垃圾收集算法是内存回收的方法论;垃圾收集器是内存回收的具体实现。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. 解决npm被墙的问题

    npm存储包文件的服务器在国外,有时候会被墙,速度很慢,所以我们需要解决这个问题. http://npm.taobao.org/  淘宝的开发团队把npm在国内做了一个备份. 安装淘宝的cnpm np ...

  2. 文件上传限制条件(JS、后缀、文件名、类型、截断)绕过及修复建议

    在现代互联网的Web应用程序中,上传文件是一 种常见的功能,因为它有助于提高业务效率,比如企业的OA系统,允许用户上传图片.视频.头像和许多其他类型的文件.然而向用户提供的功能越多,Web应用受到攻击 ...

  3. 微信小程序结合微信公众号进行消息发送

    微信小程序结合微信公众号进行消息发送 由于小程序的模板消息已经废弃了,官方让使用订阅消息功能.而订阅消息的使用限制比较大,用户必须得订阅.需要获取用户同意接收消息的权限.用户必须得和小程序有交互的时候 ...

  4. python3-day5

    模块,用一砣代码实现了某个功能的代码集合. 类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合.而对于一个复杂的功能来,可能需要多个函数才 ...

  5. 从一段 Dubbo 源码到 CPU 分支预测的一次探险之旅

    每个时代,都不会亏待会学习的人. 大家好,我是 yes. 这次本来是打算写一篇 RocketMQ 相关文章的,但是被插队了,我也是没想到的. 说来也是巧最近在看 Dubbo 源码,然后发现了一处很奇怪 ...

  6. 动态代理:jdk动态代理和cglib动态代理

    /** * 动态代理类:先参考代理模式随笔,了解代理模式的概念,分为jdk动态代理和cglib,jdk动态代理是通过实现接口的方式创建代理类的,cglib是通过继承类的方式实现的代理类的 * jdk动 ...

  7. Book of Shaders 00 - 使用 VS Code 编写 GLSL

    0x00 写在前面 最近在学习由 Patricio 编写的 The Book of Shaders,这是一本关于 Fragment Shaders(片段着色器)的入门指南.为了在一个相对熟悉的平台运行 ...

  8. WJQ与机房

    sample input 5 6 7 2 3 1 1 5 0 6 0 0 8 6 6 5 3 4 3 7 8 2 4 0 0 6 9 sample output 20 样例解释: 分别以(2,1)为左 ...

  9. Python之路——变量

    什么是变量 #变量即变化的量,核心是"变"与"量"二字,变即变化,量即衡量状态. 为什么要有变量 #程序执行的本质就是一系列状态的变化,变是程序执行的直接体现, ...

  10. 炉石传说酒馆战棋一键拔线(windows)

    小编的业余游戏之一<炉石传说>,这里分享的是现在很火的游戏拔线(跳过约20秒的战斗动画),用夜吹的话说,注意,不是"日你大坝",是"整活",哈哈.小 ...