JAVA之JVM入门

Java虚拟机(JVM)是Java平台的核心部分之一,它为Java程序提供了运行环境。

一、历史背景

1. Sun Classic VM

  • 发布时间:1996年
  • 重要功能
    • Java 1.0的默认JVM。
    • 支持基本的字节码执行。
    • 简单的垃圾回收机制。

2. HotSpot VM

  • 发布时间:1999年
  • 重要功能
    • JDK 1.3开始成为默认JVM。
    • 引入了即时编译器(JIT Compiler)。
    • 提供了多种垃圾收集器。
    • 支持线程调度和同步性能的改进。

3. JRockit VM

  • 发布时间:2000年初
  • 重要功能
    • 由BEA Systems开发,后被Oracle收购。
    • 专为高性能企业应用程序设计。
    • 强调低延迟和高吞吐量。

4. IBM J9 VM

  • 发布时间:2000年初
  • 重要功能
    • 由IBM开发,用于IBM的Java平台。
    • 高度可定制,支持多种操作系统和硬件平台。
    • 提供了广泛的性能监控和调试工具。

5、CMS(Concurrent Mark Sweep)

  • 发布时间:2004年(JDK 5.0)
  • 重要功能
    • 由Sun Microsystems开发。
    • 专注于减少垃圾收集过程中的暂停时间。
    • 实现了大部分标记和清除过程与应用程序线程并发执行。
    • 在JDK 5.0中作为实验性特性引入,在后续版本中成为稳定特性。

6. Azul VM

  • 发布时间:2000年代中期
  • 重要功能
    • 由Azul Systems开发。
    • 着重于大规模并行处理能力。
    • 支持无停顿的垃圾收集(Pauseless GC)。

7. GraalVM

  • 发布时间:2014年
  • 重要功能
    • 由Oracle Labs开发。
    • 支持多种语言(不仅仅是Java)。
    • 提供了动态编译能力,可以编译成原生镜像。

8. G1

  • 发布时间:2017年(2012年,在JDK 7 Update 4中作为实验性特性)
  • 重要功能
    • 低停顿时间:G1的目标是在保证应用运行性能的前提下,尽可能缩短GC停顿时间。
    • 内存碎片化管理:通过Region的方式减少内存碎片化的影响。
    • 自动管理:G1能够自动调整年轻代和老年代的比例,以达到预期的GC停顿时间目标。

9. ZGC

  • 发布时间:2018年(JDK 11中作为实验性特性)
  • 重要功能
    • 由Oracle开发。
    • 专注于低暂停时间的垃圾收集。
    • 在JDK 11中作为实验性特性引入,在JDK 13中成为稳定特性。

10. Shenandoah

  • 发布时间:2019年(JDK 12中作为稳定特性)
  • 重要功能
    • 专注于低暂停时间的垃圾收集。
    • 与ZGC类似,但由不同的团队开发。
    • 在JDK 12中成为稳定特性。

11. Epsilon

  • 发布时间:2019年(JDK 12中作为实验性特性)
  • 重要功能
    • 由Oracle开发。
    • 是一个极简的垃圾收集器,几乎不做任何垃圾回收工作。
    • 主要用于测试和基准测试。

二、主要垃圾收集器介绍

1、CMS

  • CMS 收集器可以在应用程序线程继续运行的同时执行大部分标记过程,从而减少了全局暂停的时间。
  • 清除不再使用的对象时,CMS 也可以与应用程序线程并发执行,进一步减少暂停时间。
  • CMS 旨在实现低暂停时间的垃圾收集,这对于响应时间敏感的应用程序尤其重要。
  • CMS 通常牺牲一定的吞吐量来换取更短的暂停时间,这是通过减少全局暂停次数和持续时间来实现的。
  • CMS 特别适合于那些需要高度响应性和低延迟的服务端应用程序。

2、G1

  • 1)内存划分:

  • G1将整个堆空间划分为多个相同大小的独立区域(Region),每个Region可以充当新生代的Eden区、Survivor区或老年代的一部分。
  • 2)并行与并发收集:

  • G1可以在多核处理器上并行执行,充分利用硬件资源。
  • 它还能够在应用程序运行时进行并发收集,以最小化垃圾收集对应用程序的影响。
  • 3)可预测的停顿时间模型:

  • G1跟踪各个Region的回收价值,并在后台维护一个优先列表,每次根据允许的收集时间优先回收价值最大的Region,保证在有限的时间内获取尽可能高的收集效率。
  • 默认停顿时间为200毫秒,可以通过-XX:MaxGCPauseMillis参数设置。
  • 4)动态调整年轻代和老年代的比例:

  • G1能够自动调整年轻代和老年代的比例,以满足停顿时间目标。
  • 新生代的大小可以在5%到60%之间通过-XX:G1NewSizePercent-XX:G1MaxNewSizePercent参数设置。
  • 5)混合回收:

  • G1不仅回收老年代的垃圾,也会回收新生代的垃圾,这种混合回收(Mixed GC)策略有助于减少Full GC的次数,提高整体性能。

3、ZGC

  • 低暂停时间:

    ZGC的主要目标是实现几乎无感的垃圾收集过程,即垃圾收集的暂停时间通常小于10毫秒,甚至在大堆内存环境中也是如此。这一特性对于实时系统和需要低延迟的应用程序非常重要。
  • 并发标记与重定位:

    • ZGC实现了并发标记和并发重定位,这意味着大多数垃圾收集工作都在应用程序运行时后台完成,减少了停顿时间。
    • 标记和重定位阶段都可以与应用程序线程并发执行。
  • 可扩展性:

    • ZGC支持大规模堆内存环境,可以处理从GB级到TB级的堆内存大小。
    • 它能够高效地利用多核处理器的能力来执行并行垃圾收集任务。
  • 自动内存管理:

    • ZGC能够自动调整堆内存的大小,不需要用户手动干预。
    • 它还可以自动调整其内部参数,以适应不同应用程序的需求。
  • 无指针压缩:

    • ZGC实现了无指针压缩的功能,这意味着在对象移动后,不需要更新堆中的所有引用。
    • 这大大减少了对象移动带来的开销,提高了垃圾收集的效率。

三、常见问题及解决方案

  • 长时间的GC停顿 (Long GC Pauses)

    • 问题描述:应用程序在运行过程中可能会经历较长的垃圾收集停顿时间,导致应用响应变慢或暂时停止响应。
    • 解决方案:
      • 使用具有较低停顿时间特性的垃圾收集器,如G1或ZGC。
      • 调整堆内存大小,适当增加堆内存大小可以减少全堆垃圾收集的发生频率。
      • 通过-XX:MaxGCPauseMillis参数设置最大允许的停顿时间,让垃圾收集器尝试在这个时间内完成工作。
  • 频繁的Minor GC (Frequent Minor GCs)

    • 问题描述:频繁的小型垃圾收集(通常涉及新生代)会导致应用程序性能下降。
    • 解决方案:
      • 增加新生代的大小,以减少垃圾收集的频率。
      • 使用并行或并发的垃圾收集器,例如Parallel或G1。
      • 调整-XX:SurvivorRatio参数来改变Survivor区与Eden区的比例,以更好地适应应用程序的工作负载。
  • Full GC (Full Garbage Collection) 频繁发生

    • 问题描述:全堆垃圾收集非常耗时,如果频繁发生,会对应用程序造成严重影响。
    • 解决方案:
      • 减少老年代的使用率,例如通过减少对象的生命周期或者避免长生命周期对象的过早晋升。
      • 使用G1或ZGC等垃圾收集器,它们旨在减少Full GC的频率。
      • 调整堆内存分配策略,比如使用-XX:+UseAdaptiveSizePolicy让JVM自动管理新生代大小。
  • 内存溢出 (OutOfMemoryError)

    • 问题描述:当堆内存不足时,JVM会抛出OutOfMemoryError异常。
    • 解决方案:
      • 增加堆内存大小,例如通过-Xmx和-Xms参数。
      • 分析应用程序的内存使用情况,识别内存泄漏并修复。
      • 使用工具如VisualVM或JConsole监控内存使用情况,并根据实际情况调整垃圾收集器的配置。
  • 内存碎片 (Memory Fragmentation)

    • 问题描述:即使总可用内存足够,但由于内存碎片化,也可能无法为大型对象分配足够的连续内存空间。
    • 解决方案:
      • 使用G1或ZGC等能够处理内存碎片的垃圾收集器,它们支持并发压缩,有助于减少内存碎片。
      • 考虑使用CMS收集器的并发模式来减少碎片化,尽管该收集器已被标记为废弃。

通过上述方法,你可以有效地解决常见的垃圾收集问题,从而提高应用程序的性能和稳定性。

四、总结

Java虚拟机(JVM)作为Java平台的核心,自1996年起历经多代发展,如Sun Classic VM、HotSpot VM等,每代都提升了性能与功能。HotSpot VM成为主流,引入JIT编译器和多种垃圾收集器(如CMS、G1、ZGC),优化线程调度与同步。垃圾收集器如CMS、G1、ZGC等,分别通过并发执行、动态调整与低停顿时间等技术,解决了长时间GC停顿、频繁Minor GC、Full GC及内存溢出与碎片等问题,保障了Java应用的性能与稳定性。JVM的持续演进与创新,为Java语言在各类场景下的广泛应用提供了坚实的基础。

 

你可能感兴趣的:(JAVA,java,jvm)