垃圾收集器

作者: 暮想sun | 来源:发表于2020-01-11 23:22 被阅读0次

    收集器之间的连线,表明可以配合使用。


    部分收集(Partial GC):

    新生代收集(Minor GC/Young GC):指目标只是新生代的垃圾收集
    老年代收集(Major GC/Old GC):指目标只是老年代的垃圾收集
    混合收集(Mixed GC):指目标是手机整个新生代以及部分老年代的垃圾收集

    整堆收集(Full GC):

    收集整个Java堆和方法区的垃圾收集。

    Full GC

    又称Major GC或老年代GC,指发生在老年代的GC;

    Serial收集器

    使用复制算法。
    新生代收集器。
    是一个单线程收集器,在垃圾收集时,必须暂停其他所有的线程,直到收集结束。
    简单高效,对于限定单个CPU环境,没有线程交互的开销,专心垃圾收集。

    应用场景:

    Client模式下默认新生代收集器。

    -XX:+UseSerialGC:参数来显式的使用Serial垃圾收集器

    ParNew收集器

    使用复制算法。
    新生代收集器。
    Serial收集器的多线程版本,在垃圾收集时,必须暂停其他所有的线程,直到收集结束。

    应用场景:

    在Server模式下,ParNew收集器是一个非常重要的收集器,因为除Serial外,目前只有它能与CMS收集器配合工作。但在单个CPU环境中,不会比Serail收集器有更好的效果,因为存在线程交互开销。

    -XX:+UseConcMarkSweepGC:指定使用CMS后,会默认使用ParNew作为新生代收集器
    -XX:+UseParNewGC:强制指定使用ParNew
    -XX:ParallelGCThreads:指定垃圾收集的线程数量,ParNew默认开启的收集线程与CPU的数量相同

    目前ParNew合并入CMS。称为专门处理新生代的组成部分,退出垃圾收集器的历史舞台。

    Parallel Scavenge收集器

    使用复制算法。
    新生代收集器。
    并行的多线程收集。

    应用场景:

    Parallel Scavenge收集器的目标则是达到一个可控制的吞吐量,适合在后台运算而不需要太多交互的任务。

    -XX:MaxGCPauseMillis:控制最大垃圾收集停顿时间,参数允许的是一个大于0的毫秒数。GC停顿时间缩短是以牺牲吞吐量和新生代空间换取的,可能会导致垃圾收集频繁。
    XX:GCTimeRatio:吞吐量的大小,参数n值0~100之内的整数。1/(1+n)=n%
    -XX:+UseAdptiveSizePolicy:开启参数后,JVM会根据当前系统运行情况收集性能监控信息,动态调整这些参数,以提供最合适的停顿时间或最大的吞吐量,这种调节方式称为GC自适应的调节策略。

    CMS为什么不能与Parallel Scavenge配合使用?

    HotSpot VM里多个GC有部分共享的代码。有一个分代式GC框架,Serial/Serial Old/ParNew/CMS都在这个框架内;在该框架内的young collector和old collector可以任意搭配使用,所谓的“mix-and-match”。
    而ParallelScavenge与G1则不在这个框架内,而是各自采用了自己特别的框架, 所以ParallelScavenge不能跟使用了那个框架的CMS搭配使用。

    Serial Old收集器

    使用标记-整理算法。
    老年代收集器。
    单线程收集。

    应用场景:

    主要应用于Client模式。
    Server模式使用:1是JDK1.5以及之前的版本中与Parallel Scavenge收集器搭配使用;2是作为CMS收集器的后背预案,在并发手机发生Concurrent Mode Failure时使用。

    Parallel Old收集器

    使用标记-整理算法。
    老年代收集器。
    多线程收集。

    应用场景:

    注重吞吐量以及CPU资源敏感的场合。

    CMS(Concurrent Mark Sweep)收集器

    是一种以获取最短回收停顿时间为目标的收集器。
    使用标记-清除算法。
    并行收集、低停顿:垃圾收集线程与用于线程同时工作

    步骤:

    1.初始标记:只是标记一下GC Roots能直接关联到的对象。
    2.并发标记:进行GC Roots Tracing的过程
    3.重新标记:为了修正并发标记期间因用户程序继续运作而导致标记发生变动的那一部分对象的标记记录。
    4.并发清除
    初始标记和重新标记,需要Stop The World

    缺点:

    1.对CPU资源非常敏感。并发收集虽然不会暂停用户线程,但因为占用一部分CPU资源,还是会导致应用程序变慢,总吞吐量降低。CMS的默认收集线程数量是=(CPU数量+3)/4。
    2.无法处理浮动垃圾,可能会出现“Concurrent Mode Failure”失败而导致另一次Full GC。
    CMS并发清理阶段,用于线程还在运行,产生新的垃圾,出现在标记之后,留待下一次GC时再清理。这一部分称之为浮动垃圾。
    并发清除时需要预留一定的内存空间,不能像其他收集器在老年代几乎填满再进行收集,可以认为CMS所需要的空间比其他垃圾收集器大。
    XX:CMSInitiatingOccupancyFraction:设置CMS触发条件,老年代使用百分比。JDK1.5默认为68%,1.6默认为92%。
    如果CMS预留内存空间无法满足程序需要,就会出现一次"Concurrent Mode Failure"失败;这时JVM启用后备预案:临时启用Serail Old收集器,而导致另一次Full GC的产生。
    3.产生大量碎片。
    -XX:+UseCMSCompactAtFullCollection:用于在CMS收集器顶不住要进行FullGC时开启碎片的合并整理过程,内存的整理过程是无法并发的,停顿时间边长。
    -XX:+CMSFullGCsBeforeCompaction:用于设值执行多少次不压缩的FullGC后,来一次压缩整理。

    应用场景:

    希望系统停顿时间最短,注重服务的响应速度。

    G1收集器:

    开创了收集器面向局部收集的设计思路和基于Region的内存布局形式。

    并发与并行:充分利用多CPU、多核的硬件优势,缩短停顿的时间,通过并发让收集与程序同时进行。
    分代收集:可独立管理整个GC堆。将整个Java堆分为多个大小相等的独立区域(Region)。
    空间整合:整体看基于标记-整理算法。从局部(两个Region)看是基于复制算法。
    可预测的停顿:建立可预测的停顿时间模型,可以有计划的避免在整个堆中进行全区域的垃圾收集。跟踪各个区域的垃圾堆积的价值大小,维护一个优先列表,每次根据允许的收集时间,优先回收价值最大的Region。

    一个对象被不同区域引用,避免扫描整个Java堆?

    无论G1还是其他分代收集器,JVM都是使用记忆集来避免全局扫描。G1每个Region都有一个对应的记忆集
    这些记忆集会记录下别的Region指向自己的指针,并标记这些指针分别在哪些卡页的范围之内。

    步骤:

    1.初始标记:仅标记一下GC Roots能直接关联到的对象,且修改TAMS(Next Top at Mark Start),让下一阶段并发运行时,用户程序能在正确可用的Region中创建新对象,需要停顿。
    2.并发标记:从GC Root开始对堆中对象进行可达性分析,找出要回收的对象,可与用户程序并发执行。耗时较长。当对象图扫描完成,还需要处理STAB记录下的在并发时有引用变动的对象。
    3.最终标记:对用户线程做另一个短暂的暂停,用于处理并发阶段结束后遗留下来的最后那少量的SATB记录。
    4.筛选回收:负责更新Region的统计数据,对各个Region的回收价值和成本进行排序,根据用户所期望的停顿时间来制定回收计划,可以自由选择任意多个Region构成回收集,然后把决定回收的那一部分Region的存活对象复制到空的Region中,再清理掉整个旧Region的全部空间。必须暂停用户线程,由多个收集器线程并发执行。

    应用场景:

    面向服务端应用,针对具有大内存、多处理器的机器

    相关文章

      网友评论

        本文标题:垃圾收集器

        本文链接:https://www.haomeiwen.com/subject/uvpbactx.html