`
zhanshenny
  • 浏览: 265609 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

JVM垃圾收集器总结

阅读更多

HotSpot JVM收集器

上面有7中收集器,分为两块,上面为新生代收集器,下面是老年代收集器。如果两个收集器之间存在连线,就说明它们可以搭配使用。

收集器
 
回收区域
特性
回收算法
使用场景
Serial(串行GC) -XX:+UseSerialGC 新生代

历史最悠久

单线程,进行垃圾收集时,必须暂停其他所有工作线程“Stop The World”

简单、高效,无线程切换开销

复制算法

JVM Client模式下默认的新生代收集器,

桌面应用

ParNew(并行GC)

-XX:+UseParNewGC

-XX:+UseConcMarkSweepGC

新生代

多线程收集,默认开启收集线程数与CPU的数量相同,

-XX: ParallelGCThreads,限制垃圾收集线程数

复制算法 Server模式下新生代收集器,首要选择

Parallel Scavenge

(并行回收GC)

-XX:+UseParallelGC(Parallel Scavenge +  Serial Old)

-XX:+UseParallelOldGC( Parallel Scavenge +  Parallel Old)

 

新生代

吞吐量优先:

它的关注点与其他收集器不同,CMS等收集器的关注点是尽可能地缩短垃圾收集时用户线程的停顿时间,而parallel Scavenge收集器的目标则是达到一个可控制的吞吐量。

吞吐量= 程序运行时间/(程序运行时间 + 垃圾收集时间)

虚拟机总共运行了100分钟。其中垃圾收集花掉1分钟,那吞吐量就是99%

 

提供两个精确控制吞吐量的参数:

-XX:MaxGCPauseMills 控制最大垃圾收集停顿时间,

-XX:GCTimeRatio 设置吞吐量大小,默认值99

 

-XX:+UseAdaptiveSizePolicy 自适应调节,是Parallel Scavenge和ParNew的重要区别

复制算法 后台运算,不需要太多交互的任务
Serial Old(串行GC) -XX:+UseParallelGC(Parallel Scavenge +  Serial Old) 老年代

单线程

与Parallel Scavenge配合

作为CMS的后备预案,在并发收集发生Concurrent Mode Failure时使用

标记-整理

Client模式

 

Parallel Old(并行GC) -XX:+UseParallelOldGC( Parallel Scavenge +  Parallel Old) 老年代

多线程

吞吐量优先

标记-整理 吞吐量优先,CPU资源敏感
CMS(并发GC) -XX:+UseConcMarkSweepGC 老年代

目的:获取最短回收停顿时间

CMS收集器的内存回收过程是与用户线程一起并发执行的。
CMS收集器的优点:
并发收集、低停顿
三个缺点:
1)CMS收集器对CPU资源非常敏感。
2)CMS收集器无法处理浮动垃圾,可能出现“Concurrent Mode Failure“,失败后而导致另一次Full  GC的产生。由于CMS并发清理阶段用户线程还在运行,伴随程序的运行自热会有新的垃圾不断产生,这一部分垃圾出现在标记过程之后,CMS无法在本次收集中处理它们,只好留待下一次GC时将其清理掉。这一部分垃圾称为“浮动垃圾”。也是由于在垃圾收集阶段用户线程还需要运行,
即需要预留足够的内存空间给用户线程使用,因此CMS收集器不能像其他收集器那样等到老年代几乎完全被填满了再进行收集,需要预留一部分内存空间提供并发收集时的程序运作使用。在默认设置下,CMS收集器在老年代使用了68%的空间时就会被激活,也可以通过参数-XX:CMSInitiatingOccupancyFraction的值来提供触发百分比,以降低内存回收次数提高性能。要是CMS运行期间预留的内存无法满足程序其他线程需要,就会出现“Concurrent Mode Failure”失败,这时候虚拟机将启动后备预案:临时启用Serial Old收集器来重新进行老年代的垃圾收集,这样停顿时间就很长了。所以说参数-XX:CMSInitiatingOccupancyFraction设置的过高将会很容易导致“Concurrent Mode Failure”失败,性能反而降低。
3)CMS是基于“标记-清除”算法实现的收集器,使用“标记-清除”算法收集后,会产生大量碎片。空间碎片太多时,将会给对象分配带来很多麻烦,比如说大对象,内存空间找不到连续的空间来分配不得不提前触发一次Full  GC。为了解决这个问题,CMS收集器提供了一个-XX:UseCMSCompactAtFullCollection开关参数,用于在Full  GC之后增加一个碎片整理过程,还可通过-XX:CMSFullGCBeforeCompaction参数设置执行多少次不压缩的Full  GC之后,跟着来一次碎片整理过程。

收集过程分为:

1)初始标记 (stop the world),仅仅只是标记出GC ROOTS能直接关联到的对象,速度很快

2)并发标记,进行GC ROOTS 根搜索算法阶段,会判定对象是否存活

3)重新标记 (stop the world)

4)并发收集

标记-清除 互联网站或者B/S系统,交互体验好
G1 -XX:+UseG1GC  

G1收集器基于“标记-整理”算法实现,也就是说不会产生内存碎片

G1垃圾收集的范围是整个Java堆(包括新生代,老年代)

化整为零,G1把整个堆划分成若干Region,后台维护一个优先列表,每次根据允许的收集时间,优先回收价值最大的Region(Gargage-First的由来)

 

收集过程分为:

1)初始标记 (stop the world)

2)并发标记

3)最终标记

4)筛选回收

标记-整理 面向服务端应用,目的是替代CMS

JVM启动参数共分为三类: 

        其一是标准参数(-),所有的JVM实现都必须实现这些参数的功能,而且向后兼容; 
        其二是非标准参数(-X),指的是JVM底层的一些配置参数,这些参数在一般开发中默认即可,不需要任何配置。但是在生产环境中,并不保证所有jvm实现都满足,所以为了提高性能,往往需要调整这些参数,以求系统达到最佳性能。
                                           另外这些参数不保证向后兼容,也即是说“如有变更,恕不在后续版本的JDK通知”(这是官网上的原话); 
        其三是非Stable参数(-XX),这类参数在jvm中是不稳定的,不适合日常使用的,后续也是可能会在没有通知的情况下就直接取消了,需要慎重使用。 

 

Full GC
        除CMS GC外,当旧生代和持久化触发GC时,其实是对新生代、旧生代及持久代都进行GC,因此通常又称为Full GC。
        当Full GC被触发时,首先按照新生代所配置的GC方式对新生代进行GC(在新生代采用PS GC时,可通过-XX:-ScavengeBeforeFullGC来禁止Full GC时对新生代进行GC),然后按照旧生代的GC方式对旧生代、持久代进行GC。但其中有一种特殊现象,如在进行Minor GC前,可能Minor GC后移到旧生代的对象多于旧生代的剩余空间,这种情况下Minor GC就不会执行了,而是直接采用旧生代的GC方式来对新生代、旧生代及持久代进行回收。 
 
除System.gc,触发Full GC的情况

1) 旧生代空间不足

    旧生代空间只有在新生代对象转入及创建为大对象、大数组时才会出现不足的现象,当执行Full GC后空间仍然不足,则抛出如下错误:

    java.lang.OutOfMemoryError: Java heap space 

   为避免以上两种状况引起的Full GC,调优时应尽量做到让对象在Minor GC阶段被回收、让对象在新生代多存活一段时间及不要创建过大的对象及数组。

2) Perman Generation空间满

    Perman Generation中存放的为一些class的信息等,当系统中要加载的类、反射的类和调用的方法较多时,Perman Generation可能会被占满,在未配置为采用CMS GC的情况下会执行Full GC。如果经过Full GC仍然回收不了,那么JVM会抛出如下错误信息:

    java.lang.OutOfMemoryError: PermGen space 

    为避免Perm Gen占满造成Full GC现象,可采用的方法为增大Perm Gen空间或转为使用CMS GC。

3) CMS GC时出现promotion failed和concurrent mode failure

    对于采用CMS进行旧生代GC的程序而言,尤其要注意GC日志中是否有promotion failed和concurrent mode failure两种状况,当这两种状况出现时可能会触发Full GC。

    promotion failed是在进行Minor GC时,survivor space放不下、对象只能放入旧生代,而此时旧生代也放不下造成的;

    concurrent mode failure是在执行CMS GC的过程中同时有对象要放入旧生代,而此时旧生代空间不足造成的。

    应对措施为:增大survivor space、旧生代空间或调低触发并发GC的比率,但在JDK 5.0+、6.0+的版本中有可能会由于JDK的bug29导致CMS在remark完毕后很久才触发sweeping动作。

    对于这种状况,可通过设置-XX: CMSMaxAbortablePrecleanTime=5(单位为ms)来避免。

4)  统计得到的Minor GC晋升到旧生代的平均大小大于旧生代的剩余空间

    这是一个较为复杂的触发情况,Hotspot为了避免由于新生代对象晋升到旧生代导致旧生代空间不足的现象,在进行Minor GC时,做了一个判断,如果之前统计所得到的Minor GC晋升到旧生代的平均大小大于旧生代的剩余空间,那么就直接触发Full GC。

    例如程序第一次触发Minor GC后,有6MB的对象晋升到旧生代,那么当下一次Minor GC发生时,首先检查旧生代的剩余空间是否大于6MB,如果小于6MB,则执行Full GC。

     当新生代采用PS GC时,方式稍有不同,PS GC是在Minor GC后也会检查,例如上面的例子中第一次Minor GC后,PS GC会检查此时旧生代的剩余空间是否大于6MB,如小于,则触发对旧生代的回收。

除了以上4种状况外,对于使用RMI来进行RPC或管理的Sun JDK应用而言,默认情况下会一小时执行一次Full GC

可通过在启动时通过- java -Dsun.rmi.dgc.client.gcInterval=3600000来设置Full GC执行的间隔时间

通过-XX:+ DisableExplicitGC来禁止RMI调用System.gc

分享到:
评论

相关推荐

    直通BAT必考题系列:7种JVM垃圾收集器特点,优劣势、及使用场景

    【JVM垃圾收集器概述】 Java虚拟机(JVM)的垃圾收集器是自动管理内存的重要组成部分,负责识别不再使用的对象并释放它们所占用的内存,以防止内存泄漏。垃圾收集器的选择和配置对应用程序的性能有着显著影响,特别...

    JVM垃圾收集器详解

    总结来说,JVM垃圾收集器通过可达性分析确定可回收对象,选择合适的时机进行回收,并利用不同的算法和收集器策略优化回收过程,以实现高效的内存管理。了解这些知识有助于理解和优化Java应用程序的性能。

    JVM入门实战/arthas实战/垃圾回收算法/垃圾回收器/jvm内存模型分析

    1.5CMS(Current Mark Sweep)收集器 1.6G1收集器 第六节:JVM参数调优 1.1 JVM重要参数介绍 1.2JVM参数调优 1.3JVM参数设置思路1.4JVM调优常用指令说明 第七节:JVM项目实战 1.1案例背景 1.2排查步骤 1.3....

    jvm垃圾回收机制总结

    二、垃圾收集器分类 1. Serial GC:单线程的垃圾回收器,适合轻量级或者对响应时间要求不高的应用。它在进行垃圾回收时会暂停其他所有工作线程,也称为"Stop-The-World"事件。 2. ParNew GC:Serial GC的多线程...

    JVM常用垃圾回收器的特性与使用场景.md

    该文档总结了JVM主要的七种垃圾回收器特点与区别,分别描述了他们作用于堆内存的哪些区域,采用单线程还是多线程工作方式,在运行过程中是否需要暂停其他用户工作线程。是笔者对周志明老师的《深入理解java虚拟机》...

    JVM性能调优总结.docx

    JVM提供了三种垃圾收集器:串行收集器、并行收集器、并发收集器。串行收集器只适用于小数据量的情况,因此这里的选择主要针对并行收集器和并发收集器。 典型配置: * -XX:+UseParallelGC:选择垃圾收集器为并行...

    Java垃圾收集器推荐.pdf

    总结而言,Java垃圾收集器是提高Java应用程序性能的关键工具之一。开发者应深入理解垃圾收集器的工作原理和特点,并结合应用需求和运行环境合理选择和配置垃圾收集策略。通过细致的性能调优,可以最大限度地减少垃圾...

    JVM高级特性之垃圾收集-黄泽忠.rar

    黄泽忠的资料深入探讨了这个主题,以下是对JVM垃圾收集的详细解析。 首先,理解JVM内存结构是至关重要的。Java内存分为堆内存和栈内存。堆内存主要存放对象实例,而栈内存用于存储方法调用时的局部变量、方法参数等...

    Java理解G1垃圾收集器.pdf

    G1垃圾收集器是Java虚拟机(JVM)的一部分,它引入了区域(Region)的概念,将堆内存划分为多个固定大小的区域,并采用分代收集策略。 在G1收集器的工作流程中,区域可以被分为新生代(Young Generation)、老年代...

    JVM的垃圾回收机制详解和调优

    JVM的垃圾回收机制是Java性能优化的关键,理解不同阶段和区域的内存分配、选择合适的垃圾收集器以及合理调整参数,可以有效提高系统性能,减少应用停顿时间,从而提升用户体验。对于大型分布式系统,深入理解JVM的GC...

    JVM内存模型和垃圾收集.pdf

    JVM提供了多种垃圾收集器,每种都有自己的特点和适用场景: 1. **串行收集器(Serial Collector)** - 适合单核处理器。 - 年轻代采用复制算法,老年代采用标记整理算法。 2. **并行收集器(Throughput Collector)*...

    计算机专业外文翻译(Java垃圾收集器)

    总结来说,这篇毕业设计论文的外文翻译深入解析了Java垃圾收集器如何运作,以及它如何通过优化内存管理来提升程序性能。通过对Java堆的动态理解和垃圾收集器的智能操作,Java能够提供一种无需程序员手动管理内存的...

    JVM中CMS收集器1

    CMS(Concurrent Mark Sweep)收集器,全称为"Mostly Concurrent Mark and Sweep Garbage Collector",是Java虚拟机(JVM)中一种旨在减少老年代(Old Generation)垃圾回收时停顿时间的并发垃圾收集器。它采用了...

    JVM总结.docx

    Java虚拟机(JVM)是Java程序运行的基础,它的核心组成部分之一就是垃圾收集器(Garbage Collector, GC)。GC的主要任务是自动管理程序中的内存,回收不再使用的对象,避免内存泄漏,确保系统的稳定运行。HotSpot ...

    JVM调优总结 -Xms -Xmx -Xmn -Xss

    可以使用 -XX:+UseParallelGC 选择垃圾收集器为并行收集器,并使用 -XX:ParallelGCThreads 配置并行收集器的线程数。 此外,还可以使用 -XX:MaxGCPauseMillis 设置每次年轻代垃圾回收的最长时间,如果无法满足此...

    JVM调优与内存管理总结

    JVM提供了多种垃圾回收器,如串行收集器(适合单CPU环境)、并行收集器(提高多CPU环境下年轻代的回收效率)和并发收集器(如CMS和G1,能够在应用程序运行时进行垃圾回收,减少停顿时间)。 串行收集器使用单线程...

    JVM 内存结构及配置总结

    JVM使用垃圾收集器来自动管理内存,主要涉及以下方面: - **垃圾收集算法**:常见的包括标记-清除、复制、标记-整理和分代收集等。 - **垃圾收集器**:包括串行收集器、并行收集器、并发收集器等,如Parallel...

    JVM内存分配与垃圾回收详解

    Java 堆也是垃圾收集器管理的主要区域,如果从内存回收的角度看,由于现在收集器采用分代收集算法所以可以分为老年代和新生代,再细致有 Eden 空间、from 空间、to 空间,但是无论怎么划分,它都是只是存储对象实例...

    JVM调优总结PDF,带原理图

    现代JVM支持多种类型的垃圾回收器,包括串行收集器、并行收集器和并发收集器。 ##### 3.1 串行收集器 串行收集器使用单线程进行垃圾回收,由于避免了多线程之间的同步开销,因此在单处理器环境下表现出较高的效率...

Global site tag (gtag.js) - Google Analytics