Java垃圾回收精粹 — Part3
Java垃圾回收精粹分4个部分,本篇是第3部分。在第3部分里介绍了串行收集器、并行收集器以及并发标记清理收集器(CMS)。
串行收集器(Serial Collector)
串行收集器是最简单的收集器,对于单处理器系统真是绝佳上选。当然,它也是所有收集器里面最不常用的。串行收集器使用一个单独的线程进行收集,不管是次要收集还是主要收集。在年老区中分配的对象使用一个简单的凹凸指针算法(bump-the-pointer algorithm)即可。当tenured space填满后会触发主要回收。
译注:按照这种技术,JVM内部维护一个allocatedTail指针,始终指向先前已分配对象的尾部。当新的对象分配请求到来时,只需检查代中剩余空间,即从allocatedTail到代尾geneTail是否足以容纳该对象,并在“满足”的情况下更新allocatedTail指针和初始化对象。
并行收集器(Parallel Collector)
并行收集器有两种形式:一种并行收集器(-XX:+ UseParallelGC)在次要回收中使用多线程来执行,在主要回收中使用单线程执行;另一种是从Java 7u4开始默认使用的并行旧生代收集器(Parallel Old collector )(XX:+UseParallelOldGC),在次要回收和主要回收均使用多线程。在tenured space分配的对象使用简单的凹凸指针(bump-the-pointer)算法即可。当年老区填满后会触发主要回收。
在多处理器系统上,并行旧生代收集器是吞吐量最大的收集器,只有收集开始时才会影响到正在运行的程序。然后使用最高效算法、多个并行线程进行收集。这使得并行旧生代收集器非常适合批处理应用。
回收年老代的成本受存留对象数量影响较大,受堆大小影响较小。要提高并行旧生代收集器的搜集效率、提供更大的吞吐量,需要更大的内存、更长的回收时间、更少的收集时暂停。
这被期望成为最快的次要回收。因为在这个收集器里,到年老区的晋升是一个简单的凹凸指针(bump-the-pointer)和复制操作。
对于服务器应用程序来说,并行旧生代收集器必须是垃圾收集的第一站。如果主要回收的暂停超过了应用程序的容忍下限,需要考虑使用与应用程序并发执行的收集器来收集年老对象。
注意:在现在的硬件条件下,对年老代的压缩每GB的存活对象预计需要暂停一到五秒。
注意:在多插槽的CPU的服务器应用程序中设置“-XX:+ UseNUMA”,可以通过并行收集器能获得更好的性能。这是因为是在线程本地的CPU插槽上分配给Eden内存。遗憾的是其他收集器不支持这个功能。
CMS(并发标记清理收集器,Concurrent Mark Sweep)
CMS(-XX:+ UseConcMarkSweepGC)收集器在年老代中使用,专门收集那些在主要回收中不可能到达的年老对象。它与应用程序并发运行,在年老代中保持一直有足够的空间以保证不会发生年轻代晋升失败。
晋升失败将会触发一次FullGC,CMS会按照下面几个步骤处理:
- 初始化标记:寻找GC根。
- 并发标记:标记所有从GC根开始可到达的对象。
- 并发预清理:检查被更新过的对象引用和在并发标记阶段晋升的对象。
- 重标记:捕捉预清洁阶段开始更新的对象引用。
- 并发清理:通过回收被死对象占用的内存更新可用空间列表。
- 并发重置:重置数据结构为下一次运行做准备。
当年老对象变得不可访问时,占用空间会被CMS回收并且放入到空闲空间列表中。当晋升发生的时候,会查询空闲空间列表,为晋升对象找到大小合适的位置。这增加了晋升的成本,因而相比并行收集器也增加了次要收集的成本。
注意:CMS 不像压缩收集器,随着时间的推移会在年老代中产生碎片。对象晋升可能失败,因为一个大对象可能在年老代在找不到一块足够容身的可用空间。如果发生了这样的事,日志会记录一条“晋升失败”的消息,然后并且触发一次FullGC来压缩存活的年老对象。对于这种压缩驱动的FullGC,由于CMS使用单线程压缩,可以想见会比使用并行旧生代收集器的主要回收使用更长的暂停时间。
CMS尽可能的与应用程序并发运行,这里面有几层含义。首先,CPU的时间会被收集器占用,因此CPU可用于应用程序的时间片减少。CMS消耗的时间量与到tenured space(老年区)的对象晋升量呈线性正相关。其次,对于并发GC周期中的某些阶段,所有的应用线程必须到达一个安全点,比如标记GC根并执行并行的重标记来检查更新。
注意:如果一个应用程序年老区的对象发生非常明显的变化,重新标记阶段将非常耗时,在极端情况下,它可能比一个完整的并行旧生代收集器的压缩时间还要长。
CMS要想降低FullGC的频率,可以通过降低吞吐量、使用更耗时的次要回收以及占用更大的空间的方式实现。 根据不同的晋升率,吞吐量会比并行收集少10%-40%。CMS同样要求多于20%的空间来存放额外的数据结构和“漂浮垃圾(floating garbage)”,漂浮垃圾是在并发标记阶段丢掉的,扔给下一个收集周期处理的对象。
高晋升率以及由此产生的碎片,有时候可以通过增加新生代和年老代空间的大小来减少。
注意:当CMS回收的空间不能满足晋升需求的时候,它可能遇到“并发模式失败(concurrent mode failures)”,在日志中可以找到记录。产生这种情况可能是因为是收集得太迟,这样可以通过调整策略来解决。也可能是收集的空间空闲率跟不上高的晋升率或则某些应用超高的对象更新率。如果你程序的晋升率和更新率太高,你可能需要改变你的应用程序来减少晋升的压力。给CMS加大内存有时候会使情况更糟,因为这需要扫描更多的内存。
Java垃圾回收精粹 — Part3的更多相关文章
- Java垃圾回收精粹 — Part4
Java垃圾回收精粹分4个部分,本篇是第4部分.在第4部分里介绍了G1收集器.其他并发收集器以及垃圾收集监控和调优. Garbage First (G1) 收集器 G1 (-XX:+UseG1GC)收 ...
- Java垃圾回收精粹 — Part2
Java垃圾回收精粹分4个部分,本篇是第2部分.在第2部分里介绍了Hotspot中的堆结构.对象分配以及次要回收. Hotspot中的堆结构 理解不同的收集器的工作方式,是探讨Java堆结构如何支持分 ...
- Java垃圾回收精粹 — Part1
Java垃圾回收精粹分4个部分,本篇是第1部分.在第1部分里介绍了权衡点.对象生命周期以及全局暂停事件. 串行.并行.并发.CMS.G1.年轻代(Young Gen).新生代(New Gen).旧生代 ...
- 【转载】Java垃圾回收机制
原文地址:http://www.importnew.com/19085.html Java垃圾回收机制 说到垃圾回收(Garbage Collection,GC),很多人就会自然而然地把它和Java联 ...
- 【转】深入理解 Java 垃圾回收机制
深入理解 Java 垃圾回收机制 一.垃圾回收机制的意义 Java语言中一个显著的特点就是引入了垃圾回收机制,使c++程序员最头疼的内存管理的问题迎刃而解,它使得Java程序员在编写程序的时候不再 ...
- 深入理解java垃圾回收机制
深入理解java垃圾回收机制---- 一.垃圾回收机制的意义 Java语言中一个显著的特点就是引入了垃圾回收机制,使c++程序员最头疼的内存管理的问题迎刃而解,它使得Java程序员在编写程序的时候不再 ...
- Java GC系列(2):Java垃圾回收是如何工作的?
本文由 ImportNew - 伍翀 翻译自 javapapers. 目录 垃圾回收介绍 垃圾回收是如何工作的? 垃圾回收的类别 垃圾回收监视和分析 本教程是为了理解基本的Java垃圾回收以及它是如何 ...
- Java GC系列(1):Java垃圾回收简介
本文由 ImportNew - 好好先生 翻译自 javapapers. Java的内存分配与回收全部由JVM垃圾回收进程自动完成.与C语言不同,Java开发者不需要自己编写代码实现垃圾回收.这是Ja ...
- Java垃圾回收介绍(译)
在Java中,对象内存空间的分配与回收是由JVM中的垃圾回收进程自动完成的.与C语言不同的是,在Java中开发者不需要专门为垃圾回收写代码.这是使Java流行的众多特征之一,也帮助了程序员写出了更好的 ...
随机推荐
- python基础(5)---整型、字符串、列表、元组、字典内置方法和文件操作介绍
对于python而言,一切事物都是对象,对象是基于类创建的,对象继承了类的属性,方法等特性 1.int 首先,我们来查看下int包含了哪些函数 # python3.x dir(int) # ['__a ...
- beego学习笔记(4):开发文档阅读(2)
bee工具的安装和使用 bee 工具是一个为了协助快速开发 beego 项目而创建的项目,通过 bee 您可以很容易的进行 beego 项目的创建.热编译.开发.测试.和部署. go get gith ...
- MVC – 5.MVC设计模式和.NetMVC框架
MVC模式-设计模式 •控制器(Controller)- 负责转发请求,对请求进行处理. •视图 (View) - 界面设计人员进行图形界面设计. •模型 (Model)-业务逻辑.数据.验证规则.数 ...
- spring-cloud-sleuth+zipkin追踪服务实现(一)
1.简述 最近在学习spring cloud构建微服务,研究追踪微服务rest服务调用链路的问题,接触到zipkin,而spring cloud也提供了spring-cloud-sleuth来方便集成 ...
- [实战]MVC5+EF6+MySql企业网盘实战(23)——文档列表
写在前面 上篇文章实现了图片列表,这篇文章实现文档列表将轻车熟路,因为逻辑基本相似,只是查询条件的不同.这里将txt,doc,docx,ppt,pptx,xls,xlsx的文件都归为文档列表中. 系列 ...
- spring boot 使用不同的profile来加载不同的配置文件
在开发过程之中,经常需要在开发和测试环境中进行互相切换,当切换的同时需要加载相应的配置文件,因此要经常 性的对配置文件进行相应的修改,长此以往感到十分痛苦.如果能针对开发和测试环境分别建两个不同的配置 ...
- Codeforces Round #393 (Div. 2) (8VC Venture Cup 2017 - Final Round Div. 2 Edition) E - Nikita and stack 线段树好题
http://codeforces.com/contest/760/problem/E 题目大意:现在对栈有m个操作,但是顺序是乱的,现在每输入一个操作要求你输出当前的栈顶, 注意,已有操作要按它们的 ...
- Docker —几个概念的理解
本文从一种使用场景来引出docker,并讨论了什么是镜像,容器,仓库,以及docker的相关概念. 试想一种使用场景: 我的wordpress 博客网站现在部署在阿里云服务器上,但是在后期的使用中我有 ...
- SQL必知必会 -------- 通配符、计算字段、函数
1.LIKE操作符 1.1百分号(%)通配符 SELECT prod_id, prod_name FROM Products WHERE prod_name LIKE 'Fish%' 此例子使用了搜索 ...
- Python之路【第六篇】:模块与包
目录 一 模块 3.1 import 3.2 from ... import... 3.3 把模块当做脚本执行 3.4 模块搜索路径 3.5 编译python文件 3.6 标准模块 3.7 dir ...