jvm的垃圾回收器,java虚拟机可以自动回收垃圾

  jvm的垃圾回收器,java虚拟机可以自动回收垃圾

  本文给大家带来了一些关于java的知识,主要整理了JVM垃圾收集器相关的问题,包括串行和串行旧收集器、ParNew收集器、并行和并行旧收集器等。下面就让我们一起来看看,希望对你有所帮助。

  如何解决写爬虫IP受阻的问题?立即使用。

  

并发与并行

   Parallel: Parallel描述多个垃圾收集器线程之间的关系,表示有多个这样的线程同时在一起工作。通常,用户线程默认处于等待状态。并发性:并发性描述了垃圾收集器线程和用户线程之间的关系,表明垃圾收集器线程和用户线程同时运行。因为用户线程没有被冻结,所以程序仍然可以响应服务请求,但是因为垃圾收集器线程占用了一些系统资源,所以应用程序的处理吞吐量会受到影响。

垃圾回收器的分类

  1. 按线程数分

  根据线程数量(用于垃圾收集)可分为串行垃圾回收器并行垃圾回收器

  串行垃圾收集器:同一时间只允许一个cPU执行垃圾收集,工作线程被挂起,直到垃圾收集完成。并行垃圾收集器:可以使用多个CPU同时执行垃圾收集。2. 按工作模式分

  按工作方式可分为并发式垃圾回收器独占式垃圾回收器。并发垃圾收集器:同一时间只允许一个cPU执行垃圾收集,工作线程被挂起,直到垃圾收集完成。独占式垃圾收集器:可以使用多个CPU同时执行垃圾收集。3. 按碎片处理方式分

  按工作方式可分为压缩式垃圾回收器非压缩式垃圾回收器

  压缩垃圾收集器会对恢复后幸存的对象进行压缩整理,消除恢复的碎片。

  

7种经典的垃圾回收器

  串行回收器:serialserial old并行回收器:ParNewParallel scavengeParallel old并发回收器:CMSG1

  新生代收集器:串联、并联和并联扫气;老年收藏者:串行老,并行老,CMS全堆收集器:G1;

垃圾回收器

  

Serial与Serial Old 回收器

  串行收集器是最基础也是最古老的收集器,曾经是(JDK 1.3.1之前)热点虚拟机新一代收集器的唯一选择。串行收集器是一个单线程工作收集器。当它收集垃圾时,所有其他工作线程都必须挂起,直到它的收集完成。

  Serialod是串行收集器的旧版本。

  串行回收器使用复制算法、串行回收和“Stop The World” 机制来执行垃圾回收。串行旧收集器标记—压缩算法、串行回收和“Stop The World” 机制执行垃圾收集。

  

ParNew 回收器

   ParNew collector本质上是串行collector的多线程并行版本。除了同时使用多个线程进行垃圾收集之外,其他行为包括所有的控制参数、收集算法、停止世界、对象分配规则、收集策略等。可用于串行收集器与串行收集器完全一致。

  

Parallel 与Parallel Old 回收器

  并联扫气收集器也是新一代收集器。也是基于标记复制算法的收集器,也是可以并行收集的多线程收集器。

  与ParNew收集器不同,并行清除收集器的目标是达到可控的吞吐量,也称为吞吐量优先垃圾收集器。

  吞吐量:处理器运行用户代码所花费的时间与处理器消耗的总时间的比率。

  高吞吐量可以最高效地利用处理器资源,尽快完成程序的计算任务,主要适用于后台不需要过多交互的分析任务。

  Parallel Old是并行清除收集器的老版本,支持多线程并发收集,基于标记-排序算法实现。

  

CMS回收器

   CMS(并发标记清除)收集器是一种目标是获得最短恢复暂停时间的收集器。

  CMS采集器基于标记-清除算法实现,其操作可分为四步,包括:

  初始标记

  最初的标记只是标记GC根可以直接关联的对象,速度很快;并发标记

  标记阶段是从GC根的直接相关对象开始遍历整个对象图的过程。这个过程需要很长时间,但不需要停止用户线程,并且可以与垃圾收集线程并发运行。注意

  重新标记阶段是对一些对象的标记记录进行修正,这些对象的标记由于用户程序在并发标记期间的连续运行而发生了变化。这一阶段的停顿时间通常略长于初始标记阶段,但也远短于并发标记阶段。并行清理

  清理标记阶段判断的死物体。因为不需要移动活动对象,所以这个阶段也可以与用户线程并发。

  CMS收集器无法处理“浮动垃圾”,有可能“顺流模式故障”会失败,导致另一个完全停止世界的完全GC。

  在CMS的并发标记和并发清理阶段,用户线程还在运行,程序的运行自然会伴随着新的垃圾对象。但是,这部分垃圾对象是在标记过程之后出现的,CMS无法在当前的收集中对其进行处理,因此必须在下一次垃圾收集时对其进行清理。这部分垃圾被称为“漂浮垃圾”。

  此外,由于用户线程在垃圾收集阶段仍然需要连续运行,因此有必要保留足够的内存空间供用户线程使用。因此,CMS收集器不能像其他收集器一样等到陈年几乎完全填满后再进行收集,必须在并发收集时为程序操作预留一些空间。

  CMS是基于“标记-清除”算法的收集器,这意味着在收集结束时会产生大量的空间碎片。当空间碎片过多时,会给大型物体的分配带来很大的麻烦。

  为什么不使用标记压缩算法来避免碎片?

  

G1(Garbage First)回收器

   Garbage首创了局部收集的收集器设计思想和基于区域的内存布局形式。它是一个主要针对服务器应用的垃圾收集器,主要针对配备多核CPU和大容量内存的机器。能够大概率满足GC暂停时间,同时具有高吞吐量的性能特点。

  对于G1之前的所有其他收集器来说,垃圾收集的目标范围要么是整个新一代,整个老年,要么是整个Java堆。G1可以面向堆内存的任何部分组成一个回收的收集组,衡量标准不再是它属于哪个分代,而 是哪块内存中存放的垃圾数量最多,回收收益最大

  

G1回收器的特点

  1. 并行与并发

  并行性:G1回收期间,多个GC线程可以同时工作。这时,用户线程停止运行。并发性:G1具有与应用程序交替执行的能力,部分工作可以与应用程序同时执行。所以一般来说,应用在整个回收阶段不会被完全屏蔽。2. 分代收集

  G1仍然是按照世代收集理论来设计的,但是其堆内存的布局与其他收集器有很大的不同:G1不再坚持固定的大小和固定数量的世代区域,而是收集器把连续的Java堆划分为多个大小相等的独立区域(Region),每一个Region都可以根据需要,扮演新生代的Eden空间、Survivor空间,或者老年代空间。可以采用不同的策略来处理扮演不同角色的区域,这样无论是新创建的对象,还是存活了一段时间并在多次收集中存活下来的老对象,都可以得到很好的收集效果。Region中还有一种特殊类型的Humongous区域,专门用来存储大型对象。G1认为,只要一个物体的大小超过一个区域容量的一半,它就可以被判断为一个大物体。3. 空间整合

  在G1内存回收中,以区域为基本单位,区域之间使用复制算法,但整体上可以看作是一种标记压缩算法。4. 可预测的停顿时间模型

  G1收集器可以建立一个可预测的暂停时间模型。它以Region作为单次收集的最小单位,即每次收集的内存空间是Region大小的整数倍,可以有计划地避免整个Java堆中的垃圾收集。G1收集器跟踪每个区域垃圾累积的“值”,价值即回收所获得的空间大小以及回收所需时间的经验值,然后在后台维护一个优先级列表。每一次,根据用户设置的允许收集暂停时间,它优先考虑那些具有最大回收价值回报的区域。这种按区域划分内存空间和优先区域回收的方法保证了G1收集器在有限的时间内获得最高的收集效率。暂停预测模型基于衰减平均值。在垃圾收集的过程中,G1收集器会记录每个可测量步骤的代价,比如每个区域的恢复时间,每个区域内存集中脏卡的数量等。并分析均值、标准差、置信度等统计信息。然后,通过这些信息,预测如果现在开始回收,回收由哪些区域组成,可以在不超过预期暂停时间的情况下获得最高收益。

Region里面存在的跨Region引用对象如何解决?

  使用内存集以避免GC根扫描时堆满。它的每个区域都有自己的记忆集。这些内存集记录其他区域指向自己的指针,并标记这些指针在哪些卡片页中。G1的内存集合在存储结构上本质上是一个哈希表,键是其他区域的起始地址,值是一个集合,其中存储的元素是卡表的索引号。

  

G1收集器的运作过程

  初始标记(初始标记):只需标记GC根可以直接关联的对象,并修改TAMS指针的值,使得下一个用户线程并发运行时,新的对象可以正确分配到可用区域。这个阶段需要停止线程,但是需要的时间很短,而且是通过借用Minor GC同步完成的,所以G1收集器在这个阶段其实没有多余的停顿。并发标记(并发标记):从GC根开始分析堆中对象的可达性,递归扫描整个堆中的对象图,找出要回收的对象。这个阶段需要很长时间,但它可以与用户程序同时执行。当对象图的扫描完成时,应该重新处理在并发期间由SATB记录的具有引用变化的对象。最终标记(最终标记):为用户线程再做一次短暂的暂停,用于处理并发阶段结束后剩下的最后几条SATB记录。筛选回收(活数据统计和疏散):负责更新区域的统计数据,对每个区域的收集值和成本进行排序,根据用户期望的暂停时间制定收集计划,自由选择任意数量的区域组成一个集合,然后将决定收集的区域的幸存对象复制到一个空区域中,然后清理整个旧区域的所有空间。这里的操作涉及幸存对象的移动,需要挂起用户线程,由多个收集器线程并行完成。

  

7种经典垃圾回收器的比较

  

垃圾回收器组合

  

低延迟垃圾收集器

  

Shenandoah收集器

   Shenandoah也使用基于区域的堆内存布局,它也有巨大的区域来存储大型对象。默认的回收策略也是优先考虑回收价值最大的区域.但是在管理堆内存方面,它与G1至少有三个明显的不同。

  G1的回收阶段可以是多线程并行的,但它不能与用户线程并发。Shenandoah支持并发排序算法。默认情况下不使用层代集合。换句话说,不会有特别的新生代区域或老一代区域。世代未实现,并不代表世代对谢南多厄一文不值。更多的是出于性价比的权衡,基于工作负载的考虑,将其放在了较低优先级的位置。Shenandoah抛弃了G1中消耗大量内存和计算资源来维护的内存集,使用一种名为“连接矩阵”的全局数据结构来记录跨区域引用关系,减少了处理跨代指针时的内存集维护消耗,也降低了假共享的概率。连接矩阵可以简单理解为一个二维表格。如果区域N中有一个对象指向区域M,在表格的N行M列做一个标记。回收时,可以通过这个表找出哪些地区有跨代引用。Nandoah收集器的工作过程大致可以分为以下九个阶段:

  初始标记:像G1一样,首先标记与GC根直接相关的对象。这个阶段仍然是“停止世界”,但暂停时间与堆大小无关,只与GC根数有关。并发标记:像G1一样,遍历对象图并标记所有可到达的对象。这个阶段与用户线程是并发的,时间的长短取决于堆中幸存对象的数量和对象图的结构复杂性。最终标记:与G1一样,处理剩余的SATB扫描,并在此阶段对具有最高恢复值的区域进行计数,并将这些区域分组到一个组中进行收集。最后阅卷阶段也会有短暂的停顿。并发清理:这个阶段用来清理那些整个区域连一个活的物体都没有的区域。并发回收:在这个阶段,Shenandoah将首先把集合中幸存的对象复制到其他未使用的区域。并发恢复阶段的持续时间取决于集合的大小。初始引用更新:在并发回收阶段复制对象后,所有对堆中旧对象的引用都需要更正为复制的新地址。这个操作被称为参考更新。事实上,引用的初始化阶段并不做任何特定的处理。这个阶段只是为了建立一个线程组装点,并确保并发回收阶段中的所有收集器线程都已经完成了分配给它们的对象移动任务。初始参考更新时间很短,会造成很短的停顿。并发引用更新:参考更新操作真正开始。这个阶段与用户线程是并发的,时间的长短取决于内存中涉及的引用数量。并发引用更新不同于并发标记。它不再需要沿着对象图搜索,只需要按照内存物理地址的顺序线性搜索出引用类型,将旧值改为新值。最终引用更新:在解决堆中的引用更新后,必须更正GC根中存在的引用。这个阶段是Shenandoah的最后一次停顿,停顿时间只与GC根数有关。并发清理:并发回收和引用更新后,整个回收集中的所有区域都没有幸存对象,这些区域成为了立即垃圾区域。最后,再次调用并发清理进程来回收这些区域的内存空间,以便将来分配新对象。

ZGC收集器

   ZGC和谢南多厄的目标非常相似。他们都希望实现低延迟,可以在任何堆内存大小下将垃圾收集的暂停时间限制在10毫秒以内,同时对吞吐量的影响尽可能小。

  ZGC收集器是一个基于区域内存布局的垃圾收集器,它(暂时)是无代的。它使用读屏障、染色指针和内存多重映射等技术实现并发标记-排序算法,其首要目标是低延迟。

  ZGC也采用基于区域的堆内存布局,但与他们不同的是,ZGC的区域具有动态3354动态创建和销毁,以及动态区域容量。

  ZGC的运作过程可以分为四个阶段:

  并发标记(:与G1和谢南多厄一样,并发标记是遍历对象图进行可达性分析的阶段。它还必须经历类似于G1和谢南多阿(虽然ZGC的名字不叫这些)的初始标记和最终标记前后的短暂停顿,这些停顿阶段所做的事情在目标上是相似的。与G1和谢南多不同,ZGC的标记是在指针上而不是在对象上完成的,标记阶段将更新染色指针中的标记0和标记1标志。并发预备重分配:这个阶段需要根据具体的查询条件,计算出本次收集过程中需要清理哪些区域,并将这些区域组成重分发集合。并发重分配:再分配是执行ZGC的核心阶段。在这个过程中,重分发集合中幸存的对象被复制到新区域,并且为重分发集合中的每个区域维护转发表,以记录从旧对象到新对象的转向关系。并发重映射:重映射所做的是在整个堆中修复对重分配集中旧对象的所有引用。ZGC巧妙地将并发重映射阶段要做的工作合并到下一个垃圾收集周期的并发标记阶段来完成。无论如何,它们都必须遍历所有的对象,因此合并节省了一次遍历对象图的开销。一旦纠正了所有指针,就可以释放最初记录新旧对象之间关系的转发表。

选择合适的垃圾收集器

  考虑以下三个问题:

  

应用程序的主要关注点是什么?

  如果是数据分析和科学计算的任务,目标是尽快计算出结果,那么主要关心的是吞吐量;如果是SLA应用,停顿时间会直接影响服务质量,甚至导致事务超时,所以延迟是主要关注的;如果是客户端应用或者嵌入式应用,垃圾回收的内存占用是不可忽视的。

运行应用的基础设施如何?

  硬件规格,要涉及的系统架构是x86-32/64,SPARC还是ARM/A Arch 64;处理器的数量和分配的内存大小;选择的操作系统是Linux、Solaris或Windows等。

使用JDK的发行商是什么?版本号是多少?

  是ZingJDK/Zulu,OracleJDK,Open-JDK,OpenJ9还是其他公司的发行?这个JDK对应《Java虚拟机规范》的哪个版本?

  

怎样选择垃圾回收器

  优先调整堆的大小,以便JVM可以自适应地完成它。如果内存小于100M,如果串行采集器是单核独立程序,对暂停时间没有要求,如果串行采集器是多CPU,要求高吞吐量,允许暂停时间超过1秒,选择并行或者JVM本身。如果是多CPU,追求低停顿时间,需要快速响应(比如互联网应用延迟不能超过1秒)。建议使用并发收集器学习:《java视频教程》以上,即Java虚拟机详细介绍:JVM。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: