JVM 垃圾收集器
基本概念
- Young Generation:新生代,hotspot vm中又细分为Eden和两个Survivor(from survivor和to survivor)
- Tenured Generation:老年代
- Minor GC:只GCyoung generation。
- Full GC、Major GC:一个意思,指GC整个heap,包括young generation和tenured generation。
先了解两个重要的垃圾收集性能的度量:
- Throughput(吞吐量) is the percentage of total time not spent in garbage collection considered over long periods of time. Throughput includes time spent in allocation (but tuning for speed of allocation is generally not needed). throughput = 运行用户代码的时间 / (运行用户代码的时间 + 垃圾收集的时间) * 100%。
- Pauses(用户线程停顿时间) are the times when an application appears unresponsive because garbage collection is occurring.因为垃圾收集而导致用户线程暂停的时长。
Hotspot包含的所有收集器:
如果两个收集器之间有连线,则这两个收集器可以搭配使用
一、Serial收集器
顾名思义,单线程收集器,“单线程”不仅仅指单个线程或者单个cpu去完成垃圾收集的工作,更重要的是在垃圾收集过程中,所有用户线程都必须暂停,等待整个垃圾收集完成后才恢复执行,官方称为“Stop The World”,新生代young neneration采用停止复制算法,老年代tenured generation采用标记整理算法(如下图)。该收集器是Hotspot在Client模式下的默认新生代young generation的收集器。
Serial收集器运行过程图示:
Serial Collector有以下特点:
- Serial Collector does Minor Collection and Full Collection serially in a stop-the-world fashion. That is, the Java application execution is halted while collection is taking place.
- Serial Collector uses the 3-area (Eden, Survivor Space "From" and Survivor Space "To") algorithm for Minor Collections in the Young Generation.改进版的停止复制算法
- Serial Collector uses the 3-step (Mark, Sweep and Compact) algorithm for Full Collections in the Tenured Generation.标记整理算法
- Serial Collector is the default garbage collector in HotSpot Client 1.5 and higher.
- Serial Collector can be specified using the "-XX:+UseSerialGC" command line option.
优点:
- 相比于其他收集器更简单高效,因为单线程没有线程切换、交互的开销。
缺点:
- Stop The World对于客户端来说可以忍受,但服务端往往不能
二、ParNew收集器
Serial收集器的多线程版本,除了使用多个线程执行垃圾收集这一点之外,其余行为和Serial收集器一致。ParNew收集器是使用-XX:+UseConcMarkSweepGC选项后的默认新生代收集器,也可以使用-XX:+UseParNewGC选项来强制指定。默认开启的线程数与CPU的数量相同,如果CPU核数较多,可通过-XX:ParallelGCThreads=<N>来指定线程个数。
ParNew收集器运行过程图示:
三、Parallel Scanvange收集器
也称Throughput Garbage Collector,是一个新生代收集器,它是使用停止复制算法的多线程收集器,这些都和ParNew收集器相同,但Parallel Scanvange收集器的目标是达到一个可控制的Throughput(吞吐量),其提供了两个参数用于精确控制吞吐量,分别是控制最大垃圾收集停顿时间的-XX:MaxGCPauseMillis=<N>(N为毫秒)以及直接设置吞吐量大小的-XX:GCTimeRatio=<N>(0 < N < 100),
-XX:MaxGCPauseMillis=<N>:N为大于0的毫秒数,收集器尽可能让垃圾收集过程花费少于N ms,你把该参数设小以后,会导致throughput也变小,因为N变小后,JVM会相应地地新生代的大小调小,从而使单次收集时间变短,但是这也就相应地导致触发GC的次数会增加,从而导致整个JVM周期内用在GC上的时间会边长,吞吐量也就变低了。所以说该收集器是以牺牲吞吐量和新生代空间来换取GC停顿时间的缩短的。
-XX:GCTimeRatio=<N>:即User time : GC time,N必须大于0小于100,例如N = 19,则允许的最大GC时间就占总时间的5%(1 / (1 + 19)* 100%)
自适应调节策略:Parallel Scanvange收集器还提供一个开关参数-XX:+UseAdaptiveSizePolicy,当打开该开关参数时,JVM会根据垃圾收集的性能信息动态调整新生代的大小、Eden和Survivor的比例(该比例是通过参数-XX:SurvivorRatio设置的)、晋升老年代对象大小(该值是通过参数-XX:PretenuredSizeThreshold指定的)。
工作过程如下图:
四、Serial Old收集器
是Serial收集器的老年代版本,也是单线程收集器。
工作过程如下图:
五、Parallel Old收集器
是Parallel Scanvange收集器的老年代版本,使用多线程和标记整理算法。
工作过程如下图:
六、CMS收集器
CMS收集器是一种以获取最短回收停顿时间为目标的收集器,采用的是标记清除算法(Mark and Sweep),整个收集过程分四个步骤:
- 初始标记(CMS Initial mark):标记GC Roots能直接关联到的对象。
- 并发标记(CMS concurrent mark):进行GC Roots Tracing的过程。
- 重新标记(CMS remark):修正并发标记阶段因用户线程继续运作而导致标记产生变动的那一部分对象的标记记录。
- 并发清除(CMS concurrent sweep):执行清除过程
耗时的两个阶段并发标记和并发清除都是收集线程和用户线程并发执行的,所以其停顿时间是很短的。
缺点:
- CMS收集器无法回收“浮动垃圾”
由于CMS并发清理阶段用户线程还在运行,伴随程序的运行自热会有新的垃圾不断产生,这一部分垃圾出现在标记过程之后,CMS无法在本次收集中处理它们,只好留待下一次GC时将其清理掉。这一部分垃圾称为“浮动垃圾”。也是由于在垃圾收集阶段用户线程还需要运行,即需要预留足够的内存空间给用户线程使用,因此CMS收集器不能像其他收集器那样等到老年代几乎完全被填满了再进行收集,需要预留一部分内存空间提供并发收集时的程序运作使用。在默认设置下,CMS收集器在老年代使用了68%的空间时就会被激活,也可以通过参数-XX:CMSInitiatingOccupancyFraction的值来提供触发百分比,以降低内存回收次数提高性能。要是CMS运行期间预留的内存无法满足程序其他线程需要,就会出现“Concurrent Mode Failure”失败,这时候虚拟机将启动后备预案:临时启用Serial Old收集器来重新进行老年代的垃圾收集,这样停顿时间就很长了。所以说参数-XX:CMSInitiatingOccupancyFraction设置的过高将会很容易导致“Concurrent Mode Failure”失败,性能反而降低。
- 内存碎片的问题:
CMS收集器是使用“标记-清除”算法收集的,这会产生大量碎片。空间碎片太多时,将会给对象分配带来很多麻烦,往往出现老年代还有很大的剩余内存空间但却找不到足够大的一块来容下一个较大的对象,从而来分配不得不提前触发一次Full GC。为了解决这个问题,CMS收集器提供了一个-XX:+UseCMSCompactAtFullCollection开关参数(默认该开关参数就是开着的),用于在Full GC时增加一个碎片整理过程,还可通过-XX:CMSFullGCBeforeCompaction参数(默认为0)设置执行多少次不带压缩的Full GC之后,跟着来一次带压缩的Full GC。
工作过程如下图:
七、G1收集器(Garbage-First)
G1是面向服务端应用的垃圾收集器,有如下特点:
- 并行与并发:G1能充分利用多CPU、多核环境下的硬件优势,使用多个CPU(CPU或者CPU核心)来缩短Stop-The-World停顿的时间,部分其他收集器原本需要停顿Java线程执行的GC动作,G1收集器仍然可以通过并发的方式让Java程序继续执行。
- 分代收集:与其他收集器一样,分代概念在G1中依然得以保留。虽然G1可以不需其他收集器配合就能独立管理整个GC堆,但它能够采用不同的方式去处理新创建的对象和已经存活了一段时间、熬过多次GC的旧对象以获取更好的收集效果。
- 空间整合:与CMS的“标记-清理”算法不同,G1从整体看来是基于“标记-整理”算法实现的收集器,从局部(两个Region之间)上看是基于“复制”算法实现,无论如何,这两种算法都意味着G1运作期间不会产生内存空间碎片,收集后能提供规整的可用内存。这种特性有利于程序长时间运行,分配大对象时不会因为无法找到连续内存空间而提前触发下一次GC。
- 可预测的停顿:这是G1相对于CMS的另外一大优势,降低停顿时间是G1和CMS共同的关注点,但G1除了追求低停顿外,还能建立可预测的停顿时间模型,能让使用者明确指定在一个长度为M毫秒的时间片段内,消耗在垃圾收集上的时间不得超过N毫秒,这几乎已经是实时Java(RTSJ)的垃圾收集器特征了。
在G1之前的其他收集器进行收集的范围都是整个新生代或者老年代,而G1不再是这样。使用G1收集器时,Java堆的内存布局与就与其他收集器有很大差别,它将整个Java堆划分为多个大小相等的独立区域
(Region),虽然还保留有新生代和老年代的概念,但新生代和老年代不再是物理隔离的了,它们都是一部分Region(不需要连续)的集合。
G1收集器之所以能建立可预测的停顿时间模型,是因为它可以有计划地避免在整个Java堆中进行全区域的垃圾收集。G1跟踪各个Region里面的垃圾堆积的价值大小(回收所获得的空间大小以及回收所需时间的经验 值),在后台维护一个优先列表,每次根据允许的收集时间,优先回价值最大的Region(这也就是Garbage-First名称的来由)。这种使用Region划分内存空间以及有优先级的区域回收方式,保证了G1收集器在有限 的时间内获可以获取尽可能高的收集效率。
相关推荐
【JVM垃圾收集器概述】 Java虚拟机(JVM)的垃圾收集器是自动管理内存的重要组成部分,负责识别不再使用的对象并释放它们所占用的内存,以防止内存泄漏。垃圾收集器的选择和配置对应用程序的性能有着显著影响,特别...
"JVM垃圾收集器特点、优劣势及使用场景" JVM垃圾收集器是Java虚拟机(JVM)中的一种自动内存管理机制,负责回收Java程序中不再使用的对象,以避免内存泄漏和提高程序性能。Java中有多种垃圾收集器,每种垃圾收集器...
在Java世界中,JVM垃圾收集器是内存管理的重要组成部分,负责自动回收不再使用的对象,以释放内存空间。垃圾收集器的选取并非一成不变,而是需要根据具体应用的需求和环境来定制。本文将详细解析几种常见的JVM垃圾...
深入理解JVM垃圾收集算法与垃圾收集器
Java虚拟机(JVM)是Java程序运行的基础,它的核心组成部分之一就是垃圾收集器(Garbage Collector, GC)。本文将全面解析JVM中的七种垃圾收集器,分析它们的特性和适用场景,帮助开发者理解如何优化Java应用的内存...
【JVM垃圾收集器详解】 Java虚拟机(JVM)中的垃圾收集器是负责自动管理内存,特别是Java堆和方法区中的对象实例。它的主要任务是识别并清理不再使用的对象,以便释放内存资源。垃圾收集涉及到三个核心问题:确定...
1.5CMS(Current Mark Sweep)收集器 1.6G1收集器 第六节:JVM参数调优 1.1 JVM重要参数介绍 1.2JVM参数调优 1.3JVM参数设置思路1.4JVM调优常用指令说明 第七节:JVM项目实战 1.1案例背景 1.2排查步骤 1.3....
在 Java 虚拟机中,GC(Garbage Collection)收集器是 JVM 的一个重要组件,它负责回收 Java 应用程序中的垃圾对象,从而维持应用程序的性能和可靠性。JvmGC 收集器是 JVM 中的三个主要 GC 收集器之一,分别是 ...
最后,JVM中提供了多种垃圾收集器,如Serial、Parallel、CMS、G1等,每种收集器都有其适用的场景和特点。例如,Serial收集器是单线程的,适用于小内存环境;而CMS(Concurrent Mark Sweep)收集器是追求低停顿时间的...
在Java编程中,JVM(Java虚拟机)的垃圾回收机制是自动管理内存的重要部分。垃圾回收机制负责回收那些不再被程序使用、即...开发者需要根据应用特点和运行环境选择合适的垃圾收集器和配置参数,以达到最优的性能表现。
常见的JVM垃圾收集器包括: - Serial收集器:单线程,适合小型应用。 - ParNew收集器:Serial的多线程版本,常与CMS配合。 - Parallel Scavenge:关注吞吐量,适用于服务器环境。 - Serial Old、Parallel Old:...
3. JVM垃圾收集器选择和配置 JVM提供了不同的垃圾收集器,包括串行收集器、并行收集器和并发标记清除(CMS)收集器。 -XX:+UseParallelGC:选择并行收集器,适用于新代(Young Generation)。 -XX:+UseParallelOldGC...
5. **参数调优建议**:根据分析结果,提供调整JVM垃圾收集器参数的建议,以优化性能。 6. **比较分析**:对比不同配置或不同时间段的GC日志,找出最佳实践。 为了有效地使用这类工具,你需要了解一些基本的JVM内存...
总结来说,卡表和写屏障是JVM垃圾收集器优化的重要组成部分。卡表提供了一种高效的方式来跟踪老年代对年轻代的引用,而写屏障则确保了这些引用的更新被正确地记录和处理。这种机制减少了全堆扫描的需求,显著提升了...
该文档总结了JVM主要的七种垃圾回收器特点与区别,分别描述了他们作用于堆内存的哪些区域,采用单线程还是多线程工作方式,在运行过程中是否需要暂停其他用户工作线程。是笔者对周志明老师的《深入理解java虚拟机》...
Java垃圾收集器是Java虚拟机(JVM)中的一种自动内存管理机制,旨在释放程序员从手动内存管理的繁琐工作中解脱出来。垃圾收集器通过跟踪对象的引用关系,确定哪些对象是可以被释放的,然后将其回收,以避免内存泄露...
得出:随着JVM的发展,默认垃圾收集器变得越来越好了。JDK 1.2及以后版本所使用的分代垃圾收集器提供了比早期JDK所使用的标记-清除-整理收集器好得多的分配和收集性能。JDK 1.4.1通过增加新的针对多处理器系统和非常...
3. **低优先级线程**:垃圾收集器通常以低优先级线程的形式运行,这意味着它只会在JVM处于空闲状态,或者系统内存压力较大时才被调度执行。这有助于平衡内存管理和应用程序性能之间的关系,避免频繁的GC操作影响程序...