前言

垃圾收集算法是内存回收的方法论;垃圾收集器是内存回收的具体实现。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. C语言实现数据结构的邻接矩阵----数组生成矩阵、打印、深度优先遍历和广度优先遍历

    写在前面 图的存储结构有两种:一种是基于二维数组的邻接矩阵表示法. 另一种是基于链表的的邻接表表示法. 在邻接矩阵中,可以如下表示顶点和边连接关系: 说明: 将顶点对应为下标,根据横纵坐标将矩阵中的某 ...

  2. Python-IndentationError: expected an indented block

    Error: IndentationError: expected an indented block Where? Python代码执行时候报这个错误 Why? Python代码具有严格缩进规范,默 ...

  3. 软件定义网络实验记录④--Open vSwitch 实验——Mininet 中使用 OVS 命令

    一.实验目的 Mininet 安装之后,会连带安装 Open vSwitch,可以直接通过 Python 脚本调用 Open vSwitch 命令,从而直接控制 Open vSwitch,通过实验了解 ...

  4. arduino中SCoop库的简单应用案例

    转载:https://www.csdn.net/gather_27/MtTaggzsMDExMS1ibG9n.html arduino中SCoop库的简单应用案例首先这篇文章来在视频https://v ...

  5. 引用类型之Array(二)

    操作方法 concat( ) concat() 方法用于连接两个或多个数组. 该方法不会改变现有的数组,而仅仅会返回被连接数组的一个副本. 语法 arrayObject.concat(arrayX,a ...

  6. CodeForces 79D 【Password】,洛谷P3943 【星空】

    其实我做的是洛谷的P3943,但是听说fstqwq窃题...... 题目描述: 小 C 拿来了一长串星型小灯泡,假装是星星,递给小 F,想让小 F 开心一点.不过,有 着强迫症的小 F 发现,这串一共 ...

  7. 跟随Javac代码来解答字节码的疑惑

    前言 本文是跟随掘金小册张师傅的<JVM字节码从入门到精通>练习而写的. 问题 问题一: 有如下代码: 1 package com.sun.tools.javac; 2 3 /** 4 * ...

  8. 2014年 实验五 Internet与网络工具的使用

    实验五 Internet与网络工具的使用 [实验目的]   ⑴.FTP服务器的架设和客户端的使用. ⑵.使用云盘和云笔记应用 ⑶.运用QQ的远程协助功能. (4).默认安装foxmail软件,进行邮件 ...

  9. 彻底根治window弹窗小广告(今日热点)

    在一个阴雨蒙蒙的下午,我上完厕所回到工位,输入锁屏密码,解锁,蹦出来三个小广告,我......这还能忍??? 废话不多说,开搞! 一.广告分为两种: 红色字的今日热点 蓝色字的今日热点 二.追溯根源: ...

  10. localhost与127.0.0.1与0.0.0.0

    localhost localhost其实是域名,一般系统默认将localhost指向127.0.0.1,但是localhost并不等于127.0.0.1,localhost指向的IP地址是可以配置的 ...