服务高峰期gc,导致服务不可用

embedded/2024/10/22 17:36:05/

随着应用程序的复杂性和负载的不断增加,对JVM进行调优,也是保障系统稳定性的一个重要方向。

需要注意,调优并非首选方案,一般来说解决性能问题还是要从应用程序本身入手(业务日志,慢请求等),只有在必要时才对jvm进行调优(gc日志和监控异常)。

下面会提供一个线上案例,说明gc调优的重要性。

02_jvm性能调优_垃圾收集器的实现-CSDN博客

调优关注指标

吞吐量

程序运行过程中执行两种任务,执行业务代码的任务和执行垃圾回收的任务;

吞吐量计算公式:CPU在用户应用程序的运行时间/(CPU在用户应用程序的运行时间+CPU在垃圾回收程序的运行时间)

简单理解就是,吞吐量大,意味着应用程序运行的时间越多,执行业务的任务越多。

那么吞吐量多大合适呢,对于我们业务系统来说,肯定是越大越好了,但吞吐量太大会导致什么问题呢?

停顿时间

因为JVM在进行垃圾回收的时候,有些特有的阶段需要停止业务程序的运行,只有这样它才能准确的找到所有可达的节点,确定哪些是垃圾对象并进行清理。

例如:gc停顿100ms,意味着在这100ms内应用程序无法运行。注意这里的停顿时长,只是JVM停止业务程序执行垃圾回收任务的时长,并不是总的垃圾回收时间(有的收集器是一个回收阶段是有多个停顿的)

堆内存大小

当gc完成后,通常会释放一大块内存空间,所以如果频繁的gc,但可用内存没有下降的趋势(或趋势比较小),通常暗示有内存泄漏的问题。

以上三者的关系

这3个指标不可能同时达到,因为他们是一个不可能的关系。

内存变大,要回收的东西肯定变多,停顿时间肯定也会延长。

吞吐量增加,必然要减少垃圾回收的频率,频率降低,垃圾回收停顿的时间也会延长。

停顿时间减少,需要增加gc的频率,导致吞吐量下降。

因此,目前的调优方向主要是吞吐量和暂停时间。(我们的目标是停顿时间竟可能小的情况下,达到最大的吞吐量)

案例-停顿时间过高

系统配置2c12g,默认使用并行回收器。

通过下图的监控,可以发现,gc频率低,但停顿时间比较长(通常停顿时间尽量不要超过300ms)

因为行回收器会导致暂停时间变长,可以考虑更换垃圾收集器(G1) -XX:+UseG1GC -XX:MaxGCPauseMillis=300 ,通过设置合理的暂停时间,减低停顿时间。

为什么没有使用cms呢?

在 JDK 1.8 中,G1 垃圾收集器(Garbage-First Garbage Collector)被引入作为一种新的选择,旨在替代老旧的 CMS(Concurrent Mark Sweep)收集器。随着 Java 平台的发展,CMS 逐渐退出了舞台,原因主要包括以下几点:

1. **停止更新和维护**:
   自 JDK 9 开始,CMS 收集器就被标记为不推荐使用(deprecated),并在后续的版本中被彻底移除。Oracle 宣布不再对 CMS 收集器进行更新和维护,这意味着任何新的性能改进或者 bug 修复都不会应用于 CMS。

2. **并发模式失败**:
   CMS 收集器在处理大量并发数据时可能会遇到 "并发模式失败"(Concurrent Mode Failure)的问题。这种情况发生时,CMS 收集器无法在用户线程运行的同时完成垃圾回收,导致它不得不进行一次完全的垃圾回收(Full GC),这将暂停所有用户线程,影响应用程序的响应时间。

3. **内存碎片问题**:
   CMS 是基于标记-清除算法的,这意味着它在回收内存时不会进行压缩,从而可能导致内存碎片。内存碎片会随着应用程序的运行逐渐累积,最终可能导致需要更大的连续内存空间时无法找到足够的空间,进而触发 Full GC。

4. **G1 收集器的优势**:
   G1 收集器被设计为一种服务器端的垃圾收集器,适用于多核处理器和大内存的机器。它具有以下优点:
   - **预测性停顿时间模型**:G1 收集器可以设置期望的停顿时间目标(Pause Time Goal),并尽可能地在这个时间内完成垃圾回收,从而提供更可控的停顿时间。
   - **并行和并发回收**:G1 能够充分利用多核处理器,同时在并发阶段减少应用程序的停顿时间。
   - **分区堆**:G1 将堆内存分割成多个区域(Region),这样可以更高效地进行垃圾回收,尤其是在处理大堆时。
   - **增量式清理**:G1 收集器可以逐步清理堆内存,而不需要一次性清理全部空间,这有助于避免长时间的停顿。
   - **压缩空间**:G1 在回收过程中可以进行空间压缩,从而减少内存碎片问题。

5. **社区和官方的推动**:
   Oracle 和 Java 社区推动使用更现代的垃圾收集器,如 G1 和后来的 ZGC(Z Garbage Collector)以及 Shenandoah,这些收集器旨在提供更低的停顿时间和更好的性能,特别是在大内存和多核心的环境中。

由于上述原因,G1 收集器成为了 JDK 9 及以后版本的默认垃圾收集器,并且随着 Java 平台的发展,G1 和其他新的垃圾收集器(如 ZGC 和 Shenandoah)继续得到改进,以满足现代应用程序对性能和响应时间的要求。


http://www.ppmy.cn/embedded/42301.html

相关文章

没有密码如何卸载卡巴斯基?

如果忘记卡巴斯基6.0的保护密码, (1)进入安全模式下 (2)打开6.0的安装目录 Kaspersky Anti-Virus 6.0: C://Program Files//Kaspersky Lab//Kaspersky Anti-Virus 6.0 (3)将目录中的avp.exe改…

K-means聚类模型教程(个人总结版)

K-means聚类是一种广泛应用于数据挖掘和数据分析的无监督学习算法。它通过将数据点分成K个簇(cluster),使得同一簇内的数据点之间的相似度最大,不同簇之间的相似度最小。本文将详细介绍K-means聚类算法的背景、基本原理、具体实现…

Java基础(三)- 多线程、网络通信、单元测试、反射、注解、动态代理

多线程基础 线程:一个程序内部的一条执行流程,只有一条执行流程就是单线程 java.lang.Thread代表线程 主线程退出,子线程存在,进程不会退出 可以使用jconsole查看 创建线程 有多个方法可以创建线程 继承Thread类 优点&#x…

PyQt5 中的 List View

文章目录 1. 基础概念2. 创建 List View2.1 PyQt5 中一个简单的 List View 实例2.2 代码解释2.3 运行结果 3. 数据模型3.1 标准模型3.2 自定义模型 4. 自定义 List View4.1 使用样式表 (QSS)4.2 设置项委托 (Item Delegate) 5.事件处理6. 与数据交互6.1 添加数据6.2 删除数据6.…

高中数学:平面向量-正交分解、坐标表示、坐标运算

一、正交分解 二、坐标表示 这里注意一点 坐标A(x,y)与向量 a → \mathop{a}\limits ^{\rightarrow} a→的坐标记作: a → \mathop{a}\limits ^{\rightarrow} a→(x,y),表示方式的区别 引申 三、加减运算的坐标表示 四、数乘运算的坐标表示 引申 两向量…

零基础学Java第十五天之正则表达式的初步理解

正则表达式的使用和理解 1、理解 正则表达式(Regular Expression,简称 regex 或 regexp)是一种强大的文本处理工具,它使用一种特定的模式来描述、匹配和操作文本字符串。正则表达式可以被用来检查一个字符串是否匹配某种模式&…

C语言游戏实战(12):植物大战僵尸(坤版)

植物大战僵尸 前言: 本游戏使用C语言和easyx图形库编写,通过这个项目我们可以深度的掌握C语言的各种语言特性和高级开发技巧,以及锻炼我们独立的项目开发能力, 在开始编写代码之前,我们需要先了解一下游戏的基本规则…

40-2 了解与安装堡垒机

堡垒机 一、堡垒机与 JumpServer 1. 堡垒机 定义: 堡垒机(Bastion Host)是一种网络安全设备,用于保障网络和数据不受外部和内部用户的入侵和破坏。它通过各种技术手段监控和记录运维人员对网络内各种设备的操作行为,以便集中报警、及时处理和审计定责。功能: 权限控制:…