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流行的众多特征之一,也帮助了程序员写出了更好的 ...
随机推荐
- IEEEXtreme 10.0 - Mancala'h
这是 meelo 原创的 IEEEXtreme极限编程大赛题解 Xtreme 10.0 - Mancala'h 题目来源 第10届IEEE极限编程大赛 https://www.hackerrank.c ...
- fastdfs5.11+centos7.2 按照部署(三)【转载】
1.测试 前面两篇博文已对FastDFS的安装和配置,做了比较详细的讲解.FastDFS的基础模块都搭好了,现在开始测试下载. 1.1 配置客户端 同样的,需要修改客户端的配置文件: vim /etc ...
- 原生js粘贴复制【源码】
<html> <head> <meta charset="UTF-8"> <title>9行代码实现复制内容至剪切板</tit ...
- webstorm自动压缩js、css、html【工具篇】
*注意:自动压缩的文件只能在同级目录下,不能指定文件夹,强制了文件自动保存,设置的手动保存将失效. 插件下载地址:点击这里下载 密码:e6bk 使用方法: 1.css&js 分别添加这两个,c ...
- LoadRunner 使用虚拟IP测试流程
LoadRunner 使用虚拟IP测试流程 LoadRunner 使用IP欺骗的原因 . 当某个IP的访问过于频繁,或者访问量过大是,服务器会拒绝访问请求,这时候通过IP欺骗可以增加访问频率和访问量, ...
- 解析Excel
package com.jpcar.utils; import java.io.File; import java.io.FileInputStream; import java.io.IOExcep ...
- 异步模型(APM)的注意事项
一.在没有线程池的前提下使用APM APM可以让线程池在异步操作完成时调用指定的回调方法.它使用很少的资源,并提供了出色的性能,然而,APM 还允许通过另外三种方式发现异步操作在何时完成. 首先,如果 ...
- 用vue-wechat-title为微信动态设置标题
1.安装插件 cnpm install vue-wechat-title --save 2.在main.js中引入 Vue.use(require('vue-wechat-title')) 3.在路由 ...
- SQL必知必会 -------- SELECT、注释
主要是看<SQL必知必会>第四版的书,而写的一些SQL笔记,红色的是方便以后查询的sql语句,工作中主要是使用mysql数据库,所以笔记也是围绕mysql而写的. 下文调试的数据表sql语 ...
- Python类总结-描述符__get__(),__set__(),__delete__()
1 描述符是什么:描述符本质就是一个新式类,在这个新式类中,至少实现了__get__(),set(),delete()中的一个,这也被称为描述符协议 get():调用一个属性时,触发 set():为一 ...