今天来总结一下最近学习到的JVM垃圾收集算法和垃圾收集器。原来以为这部分知识,对于一个Java程序员的用处不大,可是如果你的运营Web项目,出现了性能问题,那么这部分知识可以帮助你从运维的角度来优化你的项目。
首先,先讲一下JVM的垃圾收集算法,因为这是学习垃圾收集器的前堤。各种垃圾收集器也都是基于这些算法来实现的。
JVM垃圾收集算法
JVM垃圾收集算法有四种:标记-清除算法、复制算法、标记-整理算法、分代收集算法
标记-清除算法:
该算法如同它的名字一样,分为两个阶段:标记、清除。首先标记出所有需要回收的对象,然后,统一清除这些被标记的对象。该算法的缺点是:1、效率不高;2、产生大量不连续的内存碎片,导致有大量内存剩余的情况下,由于,没有连续的空间来存放较大的对象,从而触发了另一次垃圾收集动作。
复制算法:
由于标记-清除算法的效率不高,从而提出了复制算法。复制算法将可用的内存分成两样大小的两块,每次只使用其中一块内存。当这块内存用完之后,就把还存活的对象复制到另外一块上面,然后,把这块清空。复制算法克服了标记-清除算法的两个缺点,但是太浪费内存,相当于内存空间减小了一半。
随着时间的积累,现在使用的复制算法的虚拟机,不再是把内存分为1:1的两块。因为98%的对象是寿命很短的,创建之后,很快就被回收了,存活下来的只有2%,所以,用来存储存活对象的内存区,可以小一些。现在的商业虚拟机是把可用内存分为一个较大的Eden空间和两个较小的Survivor空间,每次使用Eden和其中的一块Survivor。当回收时,把Eden和Survivor中的存活对象一次复制到另一块Survivor内存区上,然后把Eden和刚才用过的Survivor空间清空。HotSpot虚拟机默认Eden和Survivor的大小比例是8:1,这样,每次新产生的对象可以使用90%的内存空间。
标记-整理算法
从名字可以看出,该算法是对“标记-清除”算法的改进升级版。同样的该算法分为两个阶段:标记、整理。标记阶段同“标记-清除”算法。整理阶段,不是直接对标记对象进行清理,而是让所有存活的对象都移动到一端,然后,直接把边界以外的内存清空。这就解决了“标记-清除”算法会造成大量不连续内存碎片的问题。
分代收集算法
分代收集算法是根据对象的存活周期的不同,将内存划分为几块。当前的商业虚拟机的垃圾收集都采用了该算法。一般把Java堆分成新生代(年轻代)和老年代(年老代)。这样就可以根据各年代中对象的存活周期来选择最合适的收集算法了。新生代,由于只有少量的对象能存活下来,所以选用“复制算法”,只需要付出少量存活对象的复制成本。老年代,由于对象的存活率高,没有额外的空间分担,就必须使用“标记-清除”或“标记-整理”算法。
JVM垃圾收集器
由于内存中的对象,是按存活周期存放在不同的内存块中的,所以,我们选择不同的算法来针对不同的内存块进行垃圾收集。从而,对于,不同的内存块,我们需要有不同的垃圾收集器。
新生代的垃圾收集器有:Serial收集器、ParNew收集器、Parallel Scavenge收集器
老年代的垃圾收集器有:Serial Old收集器、Parallel Old收集器、CMS收集器、G1收集器
下面我们来分别介绍一下这些垃圾收集器
Serial收集器/Serial Old收集器
Serial收集器/Serial Old收集器,是单线程的,使用“复制”算法。当它工作时,必须暂停其它所有工作线程。特点:简单而高效。对于运行在Client模式下的虚拟机来说是一个很好的选择。
ParNew收集器
ParNew收集器,是Serial收集器的多线程版。是运行在Server模式下的虚拟机中首选的新生代收集器。除了Serial收集器外,目前只有它能与CMS收集器配合工作。
Parallel Scavenge收集器/Parallel Old收集器
Parallel Scavenge收集器,也是使用“复制”算法的、并行的多线程收集器。这些都和ParNew收集器一样。但它关注的是吞吐量(CPU用于运行用户代码的时间与CPU总消耗时间的比值),而其它收集器(Serial/Serial Old、ParNew、CMS)关注的是垃圾收集时用户线程的停顿时间。
Parallel Old收集器是Parallel Scavenge收集器的老年代版本。
CMS收集器
CMS(Concurrent Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器,使用“标记-清除”算法。
CMS收集器分4个步骤进行垃圾收集工作:
1、初始标记 2、并发标记 3、重新标记 4、并发清除
其中“初始标记”、“重新标记”是需要暂停其它所有工作线程的。
G1收集器
G1(Garbage First)收集器,基于“标记-整理”算法,可以非常精确地控制停顿。
相关推荐
深入理解JVM垃圾收集算法与垃圾收集器
【JVM垃圾收集器概述】 Java虚拟机(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....
Java虚拟机(JVM)是Java程序运行的基础,它的核心组成部分之一就是垃圾收集器(Garbage Collector, GC)。本文将全面解析JVM中的七种垃圾收集器,分析它们的特性和适用场景,帮助开发者理解如何优化Java应用的内存...
这篇博客将探讨JVM中的基本垃圾回收算法,帮助我们更好地理解JVM内存管理的原理。 1. 标记-清除(Mark-Sweep)算法 这是最早的垃圾回收算法之一。它分为两个阶段:标记和清除。首先,从根节点开始遍历所有可达对象...
ParNew收集器是Serial收集器的多线程版本,同样适用于新生代,使用复制算法,但可以并行执行垃圾收集。默认线程数与CPU核心数相同,可调整。ParNew收集器常与CMS收集器配合使用,是Server模式下的常见选择。 3. ...
四大垃圾回收算法:复制算法、标记-清除算法、标记-整理算法、分代收集算法 七大垃圾回收器:Serial、Serial Old、ParNew、CMS、Parallel、Parallel Old、G1 JVM调优:命令行指令,设置堆内存大小的参数
JVM内存管理是Java虚拟机的核心机制之一,其主要包含对象的创建、内存分配、...通过对内存分配策略、对象生死判定、垃圾收集算法和垃圾收集器的理解与应用,可以更好地掌握JVM的内存管理,从而提升应用性能和稳定性。
本文详细探讨了JVM中的垃圾收集器和垃圾收集算法,以帮助开发者深入理解Java虚拟机的内部运作机制。 垃圾收集(GC,Garbage Collection)是JVM的一个重要功能,用于自动释放不再使用的对象所占用的内存空间,以防止...
对于任何Java开发者来说,理解和掌握JVM的性能调优、垃圾收集算法以及虚拟机的组成是提高应用程序效率的关键。 首先,我们要了解JVM的组成部分。JVM主要包括以下几个部分: 1. **类加载器(ClassLoader)**:负责...
JVM垃圾回收机制包含以下几种典型的垃圾收集算法: - 标记-清除算法:先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象。这种方法简单但效率低下,且会产生大量内存碎片。 - 复制算法:将内存...
在JVM中,性能调优是一个关键环节,特别是垃圾收集(Garbage Collection, GC)算法的选择和配置,对系统的响应时间、吞吐量以及内存使用效率有着直接影响。本文将深入探讨JVM的组成、垃圾收集的基本概念及其常见算法...
总结来说,JVM垃圾收集器通过可达性分析确定可回收对象,选择合适的时机进行回收,并利用不同的算法和收集器策略优化回收过程,以实现高效的内存管理。了解这些知识有助于理解和优化Java应用程序的性能。
在JVM的学习中,理解其内存模型、垃圾收集算法以及类加载机制至关重要。 1. **JVM内存模型** - **方法区**:也称为“永久代”,存储虚拟机加载的类信息、常量、静态变量等,是线程共享的区域。在Java 8之后,这...
Java虚拟机(JVM)垃圾收集算法是Java语言的关键特性之一,负责自动管理内存,提高软件的可靠性,并减少开发者的内存管理负担。垃圾收集机制(GC)的核心目标是识别并回收程序中不再被引用的对象,即所谓的垃圾回收...
垃圾收集器是垃圾回收算法的落地实现,包括 Serial 串行垃圾收集器、Parallel 并行垃圾收集器、CMS 并发垃圾收集器、G1 垃圾收集器等。不同的垃圾收集器适用于不同的应用场景。 在 Java 中,可以通过命令行参数来...
垃圾收集算法在JVM中的应用 垃圾收集算法是Java虚拟机(JVM)中的一种机制,用于回收堆中的无用对象,以避免内存泄露和提高系统性能。JVM中的垃圾收集算法有四种:标记-清除算法、复制算法、标记-整理算法和分代...
JVM采用了多种不同的垃圾收集算法来优化性能: 1. **复制(Copying)** - 将堆分为两个相等的空间,在进行垃圾收集时,将一个空间中的存活对象复制到另一个空间,并清空前一个空间。 - 适用于年轻代。 2. **标记...
Java垃圾收集器是Java虚拟机(JVM)中的一种自动内存管理机制,旨在释放程序员从手动内存管理的繁琐工作中解脱出来。垃圾收集器通过跟踪对象的引用关系,确定哪些对象是可以被释放的,然后将其回收,以避免内存泄露...