Java垃圾回收精粹分4个部分,本篇是第1部分。在第1部分里介绍了权衡点、对象生命周期以及全局暂停事件。

串行、并行、并发、CMS、G1、年轻代(Young Gen)、新生代(New Gen)、旧生代(Old Gen)、持久代(Perm Gen)、伊甸区(Eden)、年老区(Tenured)、幸存区(Survivor Spaces)、安全点(Safepoints)以及数百种JVM启动参数。当你试图调整垃圾回收器使你的Java应用程序获得需要的吞吐量和延迟时,这些会难倒你吗?如果回答是,你也不必担心,这样的人还有很多。文档中对垃圾收集的描述感觉就像飞机操作手册一样复杂,每个旋钮和转盘足够详尽细致,但就是搞不清如何飞起来。本文将试图解释在为特定工作负载选择和调整垃圾收集算法时需要了解的权衡点。

本文将重点关注甲骨文的HotSpot JVM和OpenJDK,这俩是最常见的。最后也会讨论其他商业JVM作为替代方案。

权衡点(The Tradeoffs)

民间有句俗话叫:“舍不得孩子套不着狼”。若我们想得到些东西,我们通常必须放弃另一些东西。当这句话用在垃圾回收上,主要通过三个变量为GC设定目标:

  1. 吞吐量:花费在垃圾收集上的时间占整个应用程序工作量的比例。通过“-XX: GCTimeRatio = 99;”来设置目标吞吐量;默认值是99,这意味着有1%的时间用于垃圾收集。
  2. 延迟:由于垃圾回收引起的响应暂停的时间。设置GC暂停的延迟使用“- XX :MaxGCPauseMillis =< n>”。
  3. 内存:我们的系统内存通常用来存储状态,在管理时经常要进行复制和移动。在任何时间点,被应用程序保留的活动对象集被称为存活集。“- Xmx<n>”用来设置最大堆大小,可以用来调节应用程序可用的堆大小。

注意:通常HotSpot不能达到这些指标,而且会没有任何警告默默地继续运行,与设定的参数值愈行愈远。

延迟散布在整个垃圾回收过程中。它会以稍稍加一些平均延迟时间为代价,减少在最坏情况下的延迟或者使延迟不会过于频繁地出现,让我们可以接受。我们不要把术语“实时”理解为尽可能小的延迟,而应当看做无论吞吐量如何都保证有一个明确的短暂延迟。

当然,对于有些程序的工作负载吞吐量是最重要的。譬如,一个长时间运行的批处理作业;如果一个批处理作业为了垃圾收集而偶尔停顿几秒,只要整体上可以更快完成那就没问题。

实际上所有其他工作负载,从人机交互的应用程序到金融交易系统,如果系统出现没有响应超过几秒钟,在某些情况下甚至是几毫秒,那麻烦就大了。在金融交易系统中牺牲吞吐量换延迟常常是值得的。当然也有可能是,应用程序被可用的物理内存数限制住却又必须保持运行,在这种情况下,我们不得不放弃对延迟和吞吐量方面的性能追求。

权衡结果通常是这样的:

  • 在很大程度上,可以使用内存消耗更多的垃圾收集算法减少垃圾收集的平均占用时间。
  • 可预见的最坏情况是延迟引发的停止响应。可以通过限制活动集(live set)和维持较小的堆来减少这种情况。
  • 可以通过管理堆和代大小,以及控制应用程序的对象分配率来减少暂停发生的频率。
  • 较长的暂停的发生频率可以通过并行运行GC和应用程序来减少,但有时会影响吞吐量。

对象生命周期

垃圾收集算法的优化通常假设大多数对象都存活了一个很短的周期,只有少部分存活时间很长。在大多数应用程序里,多数对象有一个明确的生命周期,仅有很小的一部分对象会贯穿运行整个过程。在垃圾收集理论中,这种现象通常被称为“infant mortality”(婴儿死亡率) 或 “weak generational hypothesis”(弱代假设)。譬如,循环迭代器大多生命周期极短,而静态字符串则在整个程序生命周期中都有效。

实验表明,分代垃圾收集器常常比不分代有一个数量级的提升,因而在几乎所有的服务器JVM中都使用分代垃圾回收。通过为对象分代我们知道,一块新分配对象的区域里存活对象往往非常少。因此,使用一个收集器清理这些新生的少数存活对象,并将它们拷贝到另一个年老代的区域里会很奏效。Hotspot垃圾回收器使用在GC周期中幸存的次数作为一个对象的年纪。

注意:如果你的应用程序不断产生大量对象并且存活很久,显而易见你的应用程序将要花上不少时间在垃圾回收上。同样昭然若揭的是,你会花不少时间来调优Hotspot的垃圾回收器。这种情况下,代“过滤器”不太有效。它会频繁地收集长时生存代而花费了颇多时间,最终导致了GC效率低下。年老代又那么分散,所以年老代的收集算法效率更低。分代垃圾收集器往往在两个不同回收周期操作:收集完短时间存活对象之后的次要回收(Minor collections);以及较低频率的主要回收(Major collections),即在对旧生代区域进行回收之后。

全局暂停事件(stop-the-world events)

在垃圾回收过程中的程序暂停被称之为“全局暂停事件”。在实际工程中为了进行内存管理,垃圾回收器必须定期这样做。根据不同的算法,不同的收集器会在不同的时间、不同的地方暂停整个程序。为了完全停止程序,你必须暂停所有运行中的线程。“安全点”是指在程序执行中到达的某个点,此时GC根对象全都是已知的,并且所有的堆对象的内容是一致的。当运行到 “安全点”的时候,垃圾回收器会发送一个信号让线程暂停。根据线程正在做的事情,可能需要花费一些时间才能到达“安全点”。“安全点”的检查通常是在函数的返回或者循环边界结束,但是可以进行优化使其更加动态。比如:某线程正在复制一个大数组,克隆一个大的对象,或者执行一个有限次的计数循环,这可能需要几毫秒才能到达一个“安全点”。 “安全点抵达时间”(TTSP)对于低延迟的应用非常重要。除了其他的GC标志之外,启用“XX:+PrintGCApplicationStoppedTime ”标志可以输出这个时间。

注意:对于有大量并行线程的应用程序来说,当全局暂停发生时,系统将会发生明显的调度压力并在结束后恢复。因此依赖全局暂停(stop-the-world)较少的算法会更有效率。

Java垃圾回收精粹 — Part1的更多相关文章

  1. Java垃圾回收精粹 — Part4

    Java垃圾回收精粹分4个部分,本篇是第4部分.在第4部分里介绍了G1收集器.其他并发收集器以及垃圾收集监控和调优. Garbage First (G1) 收集器 G1 (-XX:+UseG1GC)收 ...

  2. Java垃圾回收精粹 — Part3

    Java垃圾回收精粹分4个部分,本篇是第3部分.在第3部分里介绍了串行收集器.并行收集器以及并发标记清理收集器(CMS). 串行收集器(Serial Collector) 串行收集器是最简单的收集器, ...

  3. Java垃圾回收精粹 — Part2

    Java垃圾回收精粹分4个部分,本篇是第2部分.在第2部分里介绍了Hotspot中的堆结构.对象分配以及次要回收. Hotspot中的堆结构 理解不同的收集器的工作方式,是探讨Java堆结构如何支持分 ...

  4. 【转载】Java垃圾回收机制

    原文地址:http://www.importnew.com/19085.html Java垃圾回收机制 说到垃圾回收(Garbage Collection,GC),很多人就会自然而然地把它和Java联 ...

  5. 【转】深入理解 Java 垃圾回收机制

    深入理解 Java 垃圾回收机制   一.垃圾回收机制的意义 Java语言中一个显著的特点就是引入了垃圾回收机制,使c++程序员最头疼的内存管理的问题迎刃而解,它使得Java程序员在编写程序的时候不再 ...

  6. 深入理解java垃圾回收机制

    深入理解java垃圾回收机制---- 一.垃圾回收机制的意义 Java语言中一个显著的特点就是引入了垃圾回收机制,使c++程序员最头疼的内存管理的问题迎刃而解,它使得Java程序员在编写程序的时候不再 ...

  7. Java GC系列(2):Java垃圾回收是如何工作的?

    本文由 ImportNew - 伍翀 翻译自 javapapers. 目录 垃圾回收介绍 垃圾回收是如何工作的? 垃圾回收的类别 垃圾回收监视和分析 本教程是为了理解基本的Java垃圾回收以及它是如何 ...

  8. Java GC系列(1):Java垃圾回收简介

    本文由 ImportNew - 好好先生 翻译自 javapapers. Java的内存分配与回收全部由JVM垃圾回收进程自动完成.与C语言不同,Java开发者不需要自己编写代码实现垃圾回收.这是Ja ...

  9. Java垃圾回收介绍(译)

    在Java中,对象内存空间的分配与回收是由JVM中的垃圾回收进程自动完成的.与C语言不同的是,在Java中开发者不需要专门为垃圾回收写代码.这是使Java流行的众多特征之一,也帮助了程序员写出了更好的 ...

随机推荐

  1. ASPLOS'17论文导读——SC-DCNN: Highly-Scalable Deep Convolutional Neural Network using Stochastic Computing

    今年去参加了ASPLOS 2017大会,这个会议总体来说我感觉偏系统和偏软一点,涉及硬件的相对少一些,对我这个喜欢算法以及硬件架构的菜鸟来说并不算非常契合.中间记录了几篇相对比较有趣的paper,今天 ...

  2. jmeter----计数器

    在测试过程中,往往需要一些有一定规则的数字,这个时候,可以使用配置元件中的计数器去实现. 一.界面显示 二.配置说明 1.名称:标识 2.注释:备注 3.启动:是指计数器开始的值 4.递增:每次增加的 ...

  3. hdu4796

    4月真是没写啥题,这题还是月初写的…… 不错的插头dp,首先由n和m的范围知肯定是轮廓线是横向划的 问题的难点在于怎么处理下面两个问题 1.怎么处理独立插头 2.怎么处理完全将W和L左右隔开 先说独立 ...

  4. (17) go 协程管道

    一.协程 二.管道

  5. db2部署与数据仓库应用

    概念特性 安装 基础命令 连接 监控 存储过程 数据合并 Merge Into是增量备份 结果集分组 row_number() OVER (PARTITION BY COL1 ORDER BY COL ...

  6. 【交叉染色法判断二分图】Claw Decomposition UVA - 11396

    题目链接:https://cn.vjudge.net/contest/209473#problem/C 先谈一下二分图相关: 一个图是二分图的充分必要条件: 该图对应无向图的所有回路必定是偶环(构成该 ...

  7. 对java前后端分离的理解

    到目前为止,身为一个java后端开发人员的我, 在工作期间,无非就是ui设计页面,前端开发html,之后将做好的页面交给我,我负责后台逻辑一件html的页面渲染. 好好滴一个后台开发人员,莫名其妙的做 ...

  8. 洛谷——P3376 【模板】网络最大流

    题目描述 如题,给出一个网络图,以及其源点和汇点,求出其网络最大流. 输入输出格式 输入格式: 第一行包含四个正整数N.M.S.T,分别表示点的个数.有向边的个数.源点序号.汇点序号. 接下来M行每行 ...

  9. 缩略图信息提取工具vinetto

    缩略图信息提取工具vinetto   在Windows操作系统中,为了方便用户快速浏览图片,系统会自动为每个图片生成预览图.预览图默认保存在同目录的Thumbs.db文件中.当图片文件删除后,Thum ...

  10. XSS漏洞自动化攻击工具XSSer

    XSS漏洞自动化攻击工具XSSer   XSS是Web应用常见的漏洞.利用该漏洞,安全人员在网站注入恶意脚本,控制用户浏览器,并发起其他渗透操作.XSSer是Kali Linux提供的一款自动化XSS ...