当前位置: 首页 > article >正文

JVM垃圾回收器的原理和调优详解!

全文目录:

    • 开篇语
    • 前言
    • 摘要
    • 概述
    • 垃圾回收器分类及原理
      • 1. Serial 垃圾回收器
      • 2. Parallel 垃圾回收器
      • 3. CMS 垃圾回收器
      • 4. G1 垃圾回收器
    • 源码解析
      • 示例代码
    • 使用案例分享
      • 案例 1:Web 服务的 GC 调优
      • 案例 2:大数据任务的 GC 优化
    • 应用场景案例
    • 垃圾回收调优策略
    • 优缺点分析
      • 优点
      • 缺点
    • 核心类方法介绍
    • 测试用例
    • 小结
    • 总结
    • 文末

开篇语

哈喽,各位小伙伴们,你们好呀,我是喵手。运营社区:C站/掘金/腾讯云/阿里云/华为云/51CTO;欢迎大家常来逛逛

  今天我要给大家分享一些自己日常学习到的一些知识点,并以文字的形式跟大家一起交流,互相学习,一个人虽可以走的更快,但一群人可以走的更远。

  我是一名后端开发爱好者,工作日常接触到最多的就是Java语言啦,所以我都尽量抽业余时间把自己所学到所会的,通过文章的形式进行输出,希望以这种方式帮助到更多的初学者或者想入门的小伙伴们,同时也能对自己的技术进行沉淀,加以复盘,查缺补漏。

小伙伴们在批阅的过程中,如果觉得文章不错,欢迎点赞、收藏、关注哦。三连即是对作者我写作道路上最好的鼓励与支持!

前言

在上一期《JVM 对代码的几种优化手段》中,我们探讨了 JVM 如何通过即时编译(JIT)、逃逸分析、内联优化等技术来提升程序性能。这些优化手段为我们编写高效的 Java 程序提供了强大支持。然而,程序的运行不仅仅依赖于代码执行的效率,还涉及 内存管理 的有效性。

内存管理是 JVM 的核心功能之一,而 垃圾回收器(Garbage Collector, GC) 则是内存管理的关键角色。本期内容,我们将深入探讨 JVM 中垃圾回收器的工作原理,并学习如何通过调优策略提升 GC 的效率。对于 Java 开发者来说,理解垃圾回收器的运行机制以及调优技巧,是掌握 JVM 性能优化的必经之路。


摘要

本文将通过理论与实践相结合的方式,带你了解 JVM 垃圾回收器的原理、分类及调优策略。主要内容包括:

  • 垃圾回收的基础理论:JVM 内存模型与 GC 的工作机制。
  • JVM 中常见垃圾回收器的特点与适用场景。
  • 如何分析 GC 日志,并通过调优参数优化性能。
  • 实战案例:如何调优 JVM 参数以提升应用性能。
  • 垃圾回收的优缺点分析与开发中的常见问题。

通过本文的学习,你将掌握从理论到实战的完整 GC 优化技能,为你的 Java 应用程序提供坚实的性能保障。


概述

垃圾回收(Garbage Collection, GC) 是 Java 实现自动内存管理的重要组成部分。GC 的作用是回收不再被使用的对象占用的内存空间,以便分配给新的对象,同时避免内存泄漏或溢出问题。

JVM 中的垃圾回收主要针对以下区域进行管理:

  1. 堆(Heap):存放对象实例,GC 的主要工作区域。
  2. 方法区(Metaspace):存放类元数据,GC 也会在某些情况下回收这里的空间。

垃圾回收器通过以下几个步骤完成回收任务:

  1. 标记(Mark):标记所有存活的对象。
  2. 清除(Sweep):清除未被标记的对象。
  3. 整理(Compact):对存活对象进行整理,减少内存碎片。

垃圾回收器的实现基于 JVM 提供的内存分代模型:

  • 新生代:存放生命周期较短的对象,分为 Eden 和 Survivor 区。
  • 老年代:存放生命周期较长的对象。
  • 永久代/元空间:存放类元数据。

垃圾回收器分类及原理

JVM 提供了多种垃圾回收器,不同回收器适用于不同的应用场景。以下是几种常见垃圾回收器的特点和原理。

1. Serial 垃圾回收器

  • 特点:单线程工作,简单高效。
  • 适用场景:适用于单线程或小型应用。
  • 工作原理:在 GC 过程中,暂停所有用户线程(Stop-The-World, STW),依次执行标记、清除和整理操作。
-XX:+UseSerialGC

2. Parallel 垃圾回收器

  • 特点:多线程并行回收,注重吞吐量。
  • 适用场景:适用于后台批处理或大数据场景。
  • 工作原理:使用多个线程并行处理新生代和老年代的回收任务。
-XX:+UseParallelGC

3. CMS 垃圾回收器

  • 特点:低延迟回收,适合对响应时间敏感的应用。
  • 适用场景:Web 应用、在线交易系统。
  • 工作原理:分为初始标记、并发标记、重新标记和并发清理四个阶段,减少 STW 时间。
-XX:+UseConcMarkSweepGC

4. G1 垃圾回收器

  • 特点:区域化回收,兼顾吞吐量和低延迟。
  • 适用场景:需要处理大堆内存的应用。
  • 工作原理:将堆分为多个区域(Region),按优先级回收垃圾最多的区域。
-XX:+UseG1GC

源码解析

以下代码展示了 JVM 内存分代模型和垃圾回收的基本逻辑。

示例代码

public class GCDemo {public static void main(String[] args) {for (int i = 0; i < 1000; i++) {allocateMemory(); // 模拟内存分配}}private static void allocateMemory() {byte[] array = new byte[1024 * 1024]; // 分配 1MB 空间System.out.println("Allocated 1MB memory");}
}

运行时可以通过 JVM 参数查看垃圾回收过程:

java -Xmx50m -Xms50m -XX:+PrintGCDetails -XX:+UseG1GC GCDemo

运行结果(部分 GC 日志):

[GC pause (G1 Evacuation Pause) 12M->8M(50M), 0.0051236 secs]
[GC pause (G1 Humongous Allocation) 16M->12M(50M), 0.0032345 secs]

使用案例分享

案例 1:Web 服务的 GC 调优

一个高并发的 Web 服务使用 CMS 垃圾回收器,GC 频繁触发且导致长时间停顿,影响了用户体验。通过以下参数调整,显著降低了停顿时间:

-XX:+UseConcMarkSweepGC
-XX:CMSInitiatingOccupancyFraction=70
-XX:+UseCMSInitiatingOccupancyOnly

调整后,GC 触发阈值提升到 70%,减少了频繁的回收,同时保证了低延迟。

案例 2:大数据任务的 GC 优化

一个处理海量数据的批处理任务,使用 Parallel 垃圾回收器,GC 停顿时间过长。通过以下参数优化,提高了吞吐量:

-XX:+UseParallelGC
-XX:ParallelGCThreads=8
-XX:MaxGCPauseMillis=200

优化后,GC 停顿时间降低至 200 毫秒以内,任务处理效率大幅提升。


应用场景案例

  1. 低延迟系统:如在线支付、电子商务系统,适合使用 CMS 或 G1 垃圾回收器。
  2. 高吞吐量系统:如批处理、大数据系统,适合使用 Parallel 垃圾回收器。
  3. 大内存应用:如实时分析平台,适合使用 G1 垃圾回收器。

垃圾回收调优策略

  1. 分析 GC 日志:通过 -XX:+PrintGCDetails 查看 GC 情况。
  2. 选择合适的回收器:根据应用场景选择合适的 GC。
  3. 设置合理的内存分配
    • -Xms-Xmx 设置一致,避免频繁调整堆大小。
  4. 调优 GC 参数:根据需求调整线程数、暂停时间等参数。

优缺点分析

优点

  • 自动内存管理,减少开发者负担。
  • 多种垃圾回收器可选,适配不同场景。
  • 分代模型提升了内存分配和回收效率。

缺点

  • GC 停顿可能导致性能问题。
  • 调优复杂,需深入了解 JVM 运行原理。
  • 部分场景可能出现无法解决的 Full GC 问题。

核心类方法介绍

  1. java.lang.ref.Reference:用于处理软引用、弱引用和虚引用。
  2. java.lang.Runtime:提供获取 JVM 内存信息的方法,如 totalMemoryfreeMemory
  3. java.lang.management.MemoryMXBean:监控 JVM 的内存使用情况。

测试用例

import org.junit.Test;public class GCTest {@Testpublic void testGCMemoryAllocation() {byte[] array = new byte[1024 * 1024]; // 分配 1MB 空间assert array.length == 1024 * 1024;}@Testpublic void testGCBehavior() {for (int i = 0; i < 1000; i++) {byte[] array = new byte[1024 * 1024]; // 模拟内存分配}System.gc(); // 手动触发 GC}
}

小结

垃圾回收是 JVM 提升内存管理效率的重要机制。通过了解垃圾回收器的分类、原理和调优方法,开发者可以针对不同的应用场景选择合适的 GC 策略,从而提升系统性能。


总结

在本期中,我们深入探讨了 JVM 垃圾回收器的工作原理及调优策略。从 Serial 到 G1,每种垃圾回收器都有其独特的应用场景和优势。通过调优 GC 参数,我们可以进一步提升 Java 应用的性能。

下一期,我们将继续 JVM 性能优化系列,探讨 多线程与并发优化的实战技巧。希望本文能为你的 JVM 调优实践提供帮助!

… …

文末

好啦,以上就是我这期的全部内容,如果有任何疑问,欢迎下方留言哦,咱们下期见。

… …

学习不分先后,知识不分多少;事无巨细,当以虚心求教;三人行,必有我师焉!!!

wished for you successed !!!


⭐️若喜欢我,就请关注我叭。

⭐️若对您有用,就请点赞叭。
⭐️若有疑问,就请评论留言告诉我叭。


版权声明:本文由作者原创,转载请注明出处,谢谢支持!

相关文章:

JVM垃圾回收器的原理和调优详解!

全文目录&#xff1a; 开篇语前言摘要概述垃圾回收器分类及原理1. Serial 垃圾回收器2. Parallel 垃圾回收器3. CMS 垃圾回收器4. G1 垃圾回收器 源码解析示例代码 使用案例分享案例 1&#xff1a;Web 服务的 GC 调优案例 2&#xff1a;大数据任务的 GC 优化 应用场景案例垃圾回…...

与机器学习相关的概率论重要概念的介绍和说明

概率论一些重要概念的介绍和说明 1、 试验 &#xff08;1&#xff09;试验是指在特定条件下&#xff0c;对某种方法、技术、设备或产品&#xff08;即&#xff0c;事物&#xff09;进行测试或验证的过程。 &#xff08;2&#xff09;易混淆的概念是&#xff0c;实验。实验&…...

JavaScript中的相等运算符:`==`与`===`

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…...

A7. Jenkins Pipeline自动化构建过程,可灵活配置多项目、多模块服务实战

服务容器化构建的环境配置构建前需要解决什么下面我们带着问题分析构建的过程:1. 如何解决jenkins执行环境与shell脚本执行环境不一致问题?2. 构建之前动态修改项目的环境变量3. 在通过容器打包时避免不了会产生比较多的不可用的镜像资源,这些资源要是不及时删除掉时会导致服…...

66-《虞美人》

虞美人 虞美人&#xff08;学名&#xff1a;Papaver rhoeas L.&#xff09;&#xff1a;一年生草本植物&#xff0c;全体被伸展的刚毛&#xff0c;稀无毛。茎直立&#xff0c;高25-90厘米&#xff0c;具分枝。叶片轮廓披针形或狭卵形&#xff0c;羽状分裂&#xff0c;裂片披针形…...

obsidian插件——Metadata Hider

原本是要找导出图片时显示属性的插件&#xff0c;奈何还没找到&#xff0c;反而找到了可以隐藏属性的插件。唉&#xff0c;人生不如意&#xff0c;十之八九。 说一下功能&#xff1a; 这个插件可以把obsidian的文档属性放在右侧显示&#xff0c;或者决定只显示具体几项属性&a…...

MySQL中InnoDB逻辑存储结构

在MySQL中&#xff0c;InnoDB是最常用的存储引擎之一&#xff0c;它具有高度的事务支持、行级锁、ACID特性以及自动崩溃恢复等特性。InnoDB的逻辑存储结构可以分为多个层次&#xff0c;下面是详细的解析。 1. 表空间 (Tablespace) InnoDB的物理存储结构以表空间为基础。表空间…...

高阶C语言|深入理解字符串函数和内存函数

文章目录 前言1.求字符串长度1.1 字符串长度函数&#xff1a;strlen模拟实现 长度不受限制的字符串函数1.2 字符串拷贝函数&#xff1a;strcpy模拟实现 1.3 字符串连接函数&#xff1a;strcat模拟实现 1.4 字符串比较函数&#xff1a;strcmp模拟实现 长度受限制的字符串函数2.1…...

Pandas DataFrame 拼接、合并和关联

拼接:使用 pd.concat(),可以沿着行或列方向拼接 DataFrame。 合并:使用 pd.merge(),可以根据一个或多个键进行不同类型的合并(左连接、右连接、全连接、内连接)。 关联:使用 join() 方法,通常在设置了索引的 DataFrame 上进行关联操作。 concat拼接 按列拼接 df1 = …...

特种作业操作之低压电工考试真题

1.下面&#xff08; &#xff09;属于顺磁性材料。 A. 铜 B. 水 C. 空气 答案&#xff1a;C 2.事故照明一般采用&#xff08; &#xff09;。 A. 日光灯 B. 白炽灯 C. 压汞灯 答案&#xff1a;B 3.人体同时接触带电设备或线路中的两相导体时&#xff0c;电流从一相通过人体流…...

“Play around” 在编程领域的含义

“Play around” 的含义 If everything is working correctly we should have a play around in the prompt and verify that functions are actually a new type of value now, not symbols. https://www.buildyourownlisp.com/chapter11_variables 在这段话中&#xff0c;“p…...

[免费]基于Python的Django博客系统【论文+源码+SQL脚本】

大家好&#xff0c;我是java1234_小锋老师&#xff0c;看到一个不错的基于Python的Django博客系统&#xff0c;分享下哈。 项目视频演示 【免费】基于Python的Django博客系统 Python毕业设计_哔哩哔哩_bilibili 项目介绍 随着互联网技术的飞速发展&#xff0c;信息的传播与…...

通过protoc工具生成proto的pb.go文件以及使用protoc-go-inject-tag工具注入自定义标签

1.ProtoBuf认识,安装以及用法 参考:[golang 微服务] 3. ProtoBuf认识&#xff0c;安装以及golang 中ProtoBuf使用 2. 使用protoc-go-inject-tag工具注入自定义标签 这里有一个案例: syntaxproto3; package test;option go_package ".;test";message MyMessage {int6…...

进程池的制作(linux进程间通信,匿名管道... ...)

目录 一、进程间通信的理解 1.为什么进程间要通信 2.如何进行通信 二、匿名管道 1.管道的理解 2.匿名管道的使用 3.管道的五种特性 4.管道的四种通信情况 5.管道缓冲区容量 三、进程池 1.进程池的理解 2.进程池的制作 四、源码 1.ProcessPool.hpp 2.Task.hpp 3…...

Gurobi 基础语法之 tupledict 和 tuplelist

Python中的字典&#xff1a;dict 我们先来介绍一下Python语法中的 dict 类型, 字典中可以通过任意键值来对数据进行映射&#xff0c;任何无法修改的python对象都可以当作键值来使用&#xff0c;这些无法修改的Python对象包括&#xff1a;整数(比如&#xff1a;1)&#xff0c;浮…...

Flutter:搜索页,搜索bar封装

view 使用内置的Chip简化布局 import package:chenyanzhenxuan/common/index.dart; import package:ducafe_ui_core/ducafe_ui_core.dart; import package:flutter/material.dart; import package:get/get.dart; import package:tdesign_flutter/tdesign_flutter.dart;import i…...

IoTDB 2025 春节值班与祝福

2025 春节快乐 瑞蛇迎吉庆&#xff0c;祥光映华年&#xff0c;2025 春节已近在眼前。社区祝福 IoTDB 的所有关注者、支持者、使用者 2025 新年快乐&#xff0c;“蛇”来运转&#xff01; IoTDB 团队的春节放假时间为 2025 年 1 月 27 日至 2 月 4 日&#xff0c;1 月 25 日、26…...

14、Java 对象关系映射(ORM)框架:简化数据库操作的利器

嘿&#xff0c;Java 开发者们&#xff01;在我们的编程旅程中&#xff0c;经常会遇到一个重要的任务&#xff0c;那就是将 Java 对象和数据库表进行交互。传统的 JDBC 编程虽然强大&#xff0c;但代码往往会变得繁琐且容易出错。这时候&#xff0c;对象关系映射&#xff08;ORM…...

鲁滨逊漂流记读后感

前言:学校要求出鲁滨逊漂流记的读后感啊&#xff0c;那么今天我就写着试试叭&#xff0c;好久都没更新了嘤&#xff0c;可能写的不好嗷。真的不是很建议参考&#xff0c;因为我的思想可能会与学校的要求不同&#xff0c;更多的是介入了自己的思考&#xff0c;从鲁滨逊好的地方和…...

【面试】【前端】前端网络面试题总结

一、前端网络面试题总结 网络相关知识是前端开发的核心内容之一&#xff0c;面试中通常会考察协议、网络模型、性能优化及常见网络问题的处理。以下是针对前端网络面试题的总结&#xff1a; &#xff08;一&#xff09;协议森林&#xff08;大话网络协议&#xff09; 网络协议…...

【MQ】如何保证消息队列的高性能?

零拷贝 Kafka 使用到了 mmap 和 sendfile 的方式来实现零拷贝。分别对应 Java 的 MappedByteBuffer 和 FileChannel.transferTo 顺序写磁盘 Kafka 采用顺序写文件的方式来提高磁盘写入性能。顺序写文件&#xff0c;基本减少了磁盘寻道和旋转的次数完成一次磁盘 IO&#xff0…...

刀客doc:禁令影响下,TikTok广告业务正在被对手截胡

一、 现如今&#xff0c;TikTok在美国的命运迎来了暂时的反转&#xff0c;根据Adage的报道&#xff0c;广告主的投放在恢复。但短暂的关闭带来的影响依然有余震&#xff0c;一些广告主在重新评估TikTok在自己广告预算中的地位&#xff0c;这些是竞争对手截胡的机会。 长期以…...

中国电信AI大模型发布:评分超o1-preview,近屿智能带您探索AI技术新境界

近日&#xff0c;中国电信人工智能研究院宣布&#xff0c;其自主研发的复杂推理大模型TeleAI-t1-preview即将上线天翼AI开放平台。该模型采用强化学习训练方法&#xff0c;显著提升了逻辑推理和数学推导的准确性&#xff0c;展现了强大的复杂问题解决能力。 在权威评测中&#…...

服务定位器模式

服务定位器模式 引言 服务定位器模式&#xff08;Service Locator Pattern&#xff09;是一种设计模式&#xff0c;旨在解决应用程序中服务管理的问题。它通过提供一个中央服务注册中心&#xff0c;将服务提供者与服务消费者解耦&#xff0c;从而简化了服务的查找和依赖管理。…...

开发环境搭建-4:WSL 配置 docker 运行环境

在 WSL 环境中构建&#xff1a;WSL2 (2.3.26.0) Oracle Linux 8.7 官方镜像 基本概念说明 容器技术 利用 Linux 系统的 文件系统&#xff08;UnionFS&#xff09;、命名空间&#xff08;namespace&#xff09;、权限管理&#xff08;cgroup&#xff09;&#xff0c;虚拟出一…...

AI代理框架:突破LLMs极限的未来之路

标题&#xff1a;“AI代理框架&#xff1a;突破LLMs极限的未来之路” 文章信息摘要&#xff1a; 大型语言模型&#xff08;LLMs&#xff09;已接近通过预训练和数据扩展所能达到的极限&#xff0c;未来的AI进步将依赖于强化学习&#xff08;RL&#xff09;和代理框架。代理框架…...

Git 如何将旧仓库迁移新仓库中,但不显示旧的提交记录

一、异常错误 场景&#xff1a;我想把旧仓库迁移新仓库中&#xff0c;放进去之后&#xff0c;新仓库会显示这个项目之前的所有提交&#xff0c;如何不显示这些旧的提交&#xff1f; 二、原因 我们需要将旧仓库迁移新仓库中&#xff0c;但是又不想在新仓库中显示旧的提交记录…...

人工智能在计算机视觉中的应用与创新发展研究

一、引言 1.1 研究背景与意义 1.1.1 研究背景 在当今数字化与智能化飞速发展的时代&#xff0c;人工智能已成为推动各领域变革的核心力量&#xff0c;而计算机视觉作为人工智能领域中极具活力与潜力的重要分支&#xff0c;正发挥着日益关键的作用。计算机视觉旨在赋予计算机…...

使用Python和Qt6创建GUI应用程序--关于Qt的一点介绍

关于Qt的一点介绍 Qt是一个免费的开源部件工具包&#xff0c;用于创建跨平台GUI应用程序&#xff0c;允许应用程序从Windows瞄准多个平台&#xff0c;macOS&#xff0c; Linux和Android的单一代码库。但是Qt不仅仅是一个Widget工具箱和功能内置支持多媒体&#xff0c;数据库&am…...

4、PyTorch 第一个神经网络,手写神经网络的基本部分组成

假设有一个二维数据集&#xff0c;目标是根据点的位置将它们分类到两个类别中&#xff08;例如&#xff0c;红色和蓝色点&#xff09;。 以下实例展示了如何使用神经网络完成简单的二分类任务&#xff0c;为更复杂的任务奠定了基础&#xff0c;通过 PyTorch 的模块化接口&#…...