热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Java垃圾回收(4)

G1:垃圾优先G1收集器是热点JVM中要实现的最新收集器。自Java7Update4以来,它一直是受支持的收集器。OracleGC团队也公开表示

G1:垃圾优先

G1收集器是热点JVM中要实现的最新收集器。 自Java 7 Update 4以来,它一直是受支持的收集器。OracleGC团队也公开表示,他们对低暂停GC的希望是完全实现的G1。 这篇文章来自我之前的垃圾收集博客文章:

  1. 热点GC概述 。
  2. 并行垃圾收集器 。
  3. 并发标记扫描 。

问题:大堆意味着长暂停时间

并发标记和扫描(CMS)收集器是当前推荐的低暂停收集器,但是不幸的是,其暂停时间随使用权区域中活动对象的数量而定。 这意味着,尽管使用较小的堆获得较短的GC暂停相对容易,但是一旦开始使用10或100千兆字节的堆,时间就会开始增加。

CMS也不会“整理”其堆,因此在某个时间点您会遇到并发模式故障(CMF),从而触发完整的gc。 一旦进入了完整的gc场景,您就可以预期每千兆字节活动对象大约1秒钟的时间间隔。 使用CMS,您的100GB堆可能是等待1.5分钟的GC暂停滴答定时炸弹……

复制品_m67_hand_grenade_wip_by_danboldy-d4ewsgk

良好的GC调优可以解决此问题,但有时只会将问题推向前进。 并发模式失败和完整GC不可避免地会在足够长的时间范围内出现,除非您处在一小部分专门避免填充其使用期限的人员中。

G1堆布局

G1收集器试图通过将堆分成不同的区域来将单个集合的暂停时间与堆的整体大小分开。 每个区域的大小都是固定的,介于1MB和32MB之间,JVM的目标是总共创建大约2000个区域。

g1地区

您可能还记得以前的文章,其他收集器将堆分为Eden,Survior Space和Tenured内存池。 G1保留相同类别的池,但不是将它们作为连续的内存块,而是将每个区域在逻辑上分类为这些池之一。

还有另一种类型的区域-大型区域。 这些对象用于存储大小比大多数对象大的对象,例如,很长的数组。 任何大于区域大小50%的对象都存储在巨大的区域中。 它们通过获取连续位于内存中的多个普通区域并将它们视为单个逻辑区域来工作。

g1区域类型

记忆集

当然,如果您将不得不扫描整个堆以找出哪些对象被标记为活动对象,那么将堆分成多个区域毫无意义。 实现此目标的第一步是将区域分成称为卡的512字节段。 每张卡在卡标记表中都有一个1字节的条目。

每个区域都有一个关联的记忆集或RSet-这是已写入的卡集。 如果卡片中存储的另一个区域中的某个对象指向该区域中的某个对象,则卡片在记忆集中。

每当更改器写入对象引用时,就会使用写屏障来更新所记住的集合。 在幕后,记住的集合被分为不同的集合,以便不同的线程可以在没有争用的情况下运行,但是从概念上讲,所有集合都是同一集合的一部分。

并发标记

为了标识哪些堆对象是活动的,G1执行活动对象的大部分并发标记。

  • 标记阶段标记阶段的目标是弄清楚堆中哪些对象是活动的。 为了存储哪些对象处于活动状态,G1使用了标记位图-堆中每64位存储一个位。 从所有对象的根部开始跟踪,并在标记位图中使用活动对象标记区域。 这通常是并发的,但是有一个类似于CMS的“ 初始标记暂停” ,其中应用程序被暂停并且跟踪根对象的第一级子级。 完成此步骤后,重新启动线程。 G1需要保持对堆中生活内容的最新了解,因为不会在标记阶段的同一暂停中清理堆。
  • 标记阶段标记阶段的目标是使标记阶段中有关活动对象的信息保持最新。 首先要做的是确定何时进行标记。 由一定百分比的堆已满触发。 这是通过从标记阶段和此后的分配数量中获取信息来计算的,并告诉G1其是否超过了要求的百分比。 G1使用前面提到的写屏障来记录对堆的更改,并将其存储在一系列更改缓冲区中 。 更改缓冲区中的对象同时在标记位图中标记。 当达到填充百分比时,将再次暂停更改程序线程并处理更改缓冲区,从而将更改缓冲区中的对象标记为活动状态。
  • 清理阶段此时,G1知道哪些对象处于活动状态。 由于G1专注于可用空间最大的区域,因此下一步是通过对活动对象进行计数来计算给定区域中的可用空间。 这是从标记位图计算得出的,并且根据最有可能收集到哪些区域来对区域进行排序。 要收集的区域存储在所谓的收集集或CSet中

疏散

与半球年轻一代在并行GC和CMS收集器中采用的方法类似,不会收集死物。 取而代之的是,将有生命的物体从某个区域撤离,然后将整个区域视为空闲区域。

G1对于如何回收活动物体很聪明–它不会尝试在给定的周期内回收所有活动物体。 它针对的是可能会回收尽可能多空间的区域,仅将其撤离。 它通过计算活动对象在一个区域内的比例并选择活动对象比例最低的区域来确定其目标区域。

将物体从多个其他区域撤离到自由区域。 这意味着G1在执行GC时会压缩数据。 这由多个线程并行操作。 传统的“平行GC”可以做到这一点,而CMS不这样做。

与CMS和Parallel GC相似,存在终身制的概念。 也就是说,如果年轻对象在足够的收藏中存活下来,它们就会变“旧”。 此数字称为任职期限。 如果年轻的世代区域在任职期限内幸免,并保留了足够的活物以避免被疏散,则该区域将得到提升。 首先是幸存者,最后是终身制地区。 它从未被疏散。

疏散失败

不幸的是,G1仍然会遇到类似于并发模式故障的情况,在这种情况下,它会退回到Stop the World Full GC。 这称为疏散失败,在没有空闲区域时发生。 没有自由区域意味着没有地方疏散物体。

理论上,与CMS中的并发模式故障相比,G1中发生疏散失败的可能性较小。 这是因为G1会即时压缩其区域,而不仅仅是等待压缩失败。

结论

尽管进行了压缩和在低暂停时做出的努力,但G1并不能保证一定会获胜,采用它的任何尝试都应伴随有客观且可衡量的性能目标以及GC Log分析。 所需的方法超出了本博客文章的范围,但希望我会在以后的文章中介绍它。

从算法上讲,G1会遇到其他Hotspot收集器不会遇到的开销。 值得注意的是,维护记忆集的成本。 并行GC仍然是推荐的吞吐量收集器,并且在许多情况下CMS都比G1更好。

现在说G1是否会比CMS收集器大胜还为时过早,但是在某些情况下,它已经为使用它的开发人员提供了好处。 随着时间的流逝,我们将看到G1的性能限制是否真的是G1的限制,或者开发团队是否仅需要更多的工程工作来解决那里的问题。

感谢John Oliver , Tim Monks和Martijn Verburg审阅了本期及以前的GC文章的草稿。

参考: Insightful Logic博客上来自我们JCG合作伙伴 Richard Warburton的Java垃圾收集(4) 。

翻译自: https://www.javacodegeeks.com/2013/07/garbage-collection-in-java-4.html



推荐阅读
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • Redis底层数据结构之压缩列表的介绍及实现原理
    本文介绍了Redis底层数据结构之压缩列表的概念、实现原理以及使用场景。压缩列表是Redis为了节约内存而开发的一种顺序数据结构,由特殊编码的连续内存块组成。文章详细解释了压缩列表的构成和各个属性的含义,以及如何通过指针来计算表尾节点的地址。压缩列表适用于列表键和哈希键中只包含少量小整数值和短字符串的情况。通过使用压缩列表,可以有效减少内存占用,提升Redis的性能。 ... [详细]
  • 本文介绍了Oracle存储过程的基本语法和写法示例,同时还介绍了已命名的系统异常的产生原因。 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • Nginx使用(server参数配置)
    本文介绍了Nginx的使用,重点讲解了server参数配置,包括端口号、主机名、根目录等内容。同时,还介绍了Nginx的反向代理功能。 ... [详细]
  • Webpack5内置处理图片资源的配置方法
    本文介绍了在Webpack5中处理图片资源的配置方法。在Webpack4中,我们需要使用file-loader和url-loader来处理图片资源,但是在Webpack5中,这两个Loader的功能已经被内置到Webpack中,我们只需要简单配置即可实现图片资源的处理。本文还介绍了一些常用的配置方法,如匹配不同类型的图片文件、设置输出路径等。通过本文的学习,读者可以快速掌握Webpack5处理图片资源的方法。 ... [详细]
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
  • 高质量SQL书写的30条建议
    本文提供了30条关于优化SQL的建议,包括避免使用select *,使用具体字段,以及使用limit 1等。这些建议是基于实际开发经验总结出来的,旨在帮助读者优化SQL查询。 ... [详细]
  • 本文介绍了南邮ctf-web的writeup,包括签到题和md5 collision。在CTF比赛和渗透测试中,可以通过查看源代码、代码注释、页面隐藏元素、超链接和HTTP响应头部来寻找flag或提示信息。利用PHP弱类型,可以发现md5('QNKCDZO')='0e830400451993494058024219903391'和md5('240610708')='0e462097431906509019562988736854'。 ... [详细]
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
  • Windows7 64位系统安装PLSQL Developer的步骤和注意事项
    本文介绍了在Windows7 64位系统上安装PLSQL Developer的步骤和注意事项。首先下载并安装PLSQL Developer,注意不要安装在默认目录下。然后下载Windows 32位的oracle instant client,并解压到指定路径。最后,按照自己的喜好对解压后的文件进行命名和压缩。 ... [详细]
  • 一句话解决高并发的核心原则
    本文介绍了解决高并发的核心原则,即将用户访问请求尽量往前推,避免访问CDN、静态服务器、动态服务器、数据库和存储,从而实现高性能、高并发、高可扩展的网站架构。同时提到了Google的成功案例,以及适用于千万级别PV站和亿级PV网站的架构层次。 ... [详细]
  • 在Oracle11g以前版本中的的DataGuard物理备用数据库,可以以只读的方式打开数据库,但此时MediaRecovery利用日志进行数据同步的过 ... [详细]
author-avatar
手机用户2502875747
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有