📕我是廖志伟,一名Java开发工程师、《Java项目实战——深入理解大型互联网企业通用技术》(基础篇)、(进阶篇)、(架构篇)清华大学出版社签约作家、Java领域优质创作者、优快云博客专家、阿里云专家博主、51CTO专家博主、产品软文专业写手、技术文章评审老师、技术类问卷调查设计师、幕后大佬社区创始人、开源项目贡献者。
📘拥有多年一线研发和团队管理经验,研究过主流框架的底层源码(Spring、SpringBoot、SpringMVC、SpringCloud、Mybatis、Dubbo、Zookeeper),消息中间件底层架构原理(RabbitMQ、RocketMQ、Kafka)、Redis缓存、MySQL关系型数据库、 ElasticSearch全文搜索、MongoDB非关系型数据库、Apache ShardingSphere分库分表读写分离、设计模式、领域驱动DDD、Kubernetes容器编排等。不定期分享高并发、高可用、高性能、微服务、分布式、海量数据、性能调优、云原生、项目管理、产品思维、技术选型、架构设计、求职面试、副业思维、个人成长等内容。
🌾阅读前,快速浏览目录和章节概览可帮助了解文章结构、内容和作者的重点。了解自己希望从中获得什么样的知识或经验是非常重要的。建议在阅读时做笔记、思考问题、自我提问,以加深理解和吸收知识。阅读结束后,反思和总结所学内容,并尝试应用到现实中,有助于深化理解和应用知识。与朋友或同事分享所读内容,讨论细节并获得反馈,也有助于加深对知识的理解和吸收。💡在这个美好的时刻,笔者不再啰嗦废话,现在毫不拖延地进入文章所要讨论的主题。接下来,我将为大家呈现正文内容。
在深入探讨JVM(Java虚拟机)的知识体系之前,我们先来了解一下JVM的基本概念。JVM是一个可以执行Java字节码的虚拟机,它是Java平台的核心组件之一,负责将Java代码编译成的字节码转换为机器码执行,从而实现跨平台运行。以下是JVM知识体系中的关键知识点:
类加载机制
类加载机制是JVM的一个重要组成部分,负责在运行时将类定义(.class文件)加载到JVM中。类加载机制包括以下几个关键概念:
- 类加载器:负责将类定义加载到JVM中。在Java中,主要有以下几种类加载器:
- Bootstrap ClassLoader:负责加载Java的核心类库,如rt.jar中的类。
- Extension ClassLoader:负责加载Java的扩展库。
- App ClassLoader:负责加载应用程序中的类。
- 自定义类加载器:用户自定义的类加载器。
- 类加载过程:包括三个阶段:加载、连接和初始化。
- 加载:查找并加载类定义到JVM中。这个过程涉及类的二进制数据的加载到方法区中。
- 连接:验证类定义的正确性,准备类变量和静态常量。
- 验证:确保加载的类符合Java语言规范。
- 准备:为类变量分配内存并设置默认值。
- 解析:将符号引用转换为直接引用。
- 初始化:执行类构造器( ())方法,初始化类变量、静态常量和静态代码块。
双亲委派模型
双亲委派模型是JVM中类加载器的一种工作模式,其中,子类加载器会先请求父类加载器进行类的加载,只有当父类加载器无法完成加载时,才会尝试由子类加载器加载。这种模型保证了Java类的单例性,避免了类的重复加载。
自定义类加载器
在特定场景下,可能需要自定义类加载器,例如实现模块化系统(JPMS)。自定义类加载器可以通过继承ClassLoader类并重写findClass方法来实现。
模块化系统(JPMS)
模块化系统是Java 9引入的新特性,它允许开发者将应用程序分解为多个模块,从而提高系统的可维护性和性能。模块化系统通过模块描述文件(module-info.java)来定义模块的依赖关系,并通过模块路径(modulepath)和类路径(classpath)来加载模块。
内存模型
JVM的内存模型分为以下几个区域:
- 运行时数据区:包括堆、栈、方法区和PC寄存器。
- 堆:存储所有类的实例和数组的对象。堆内存的大小可以通过JVM参数设置。
- 栈:存储局部变量和方法调用栈。每个线程都有独立的栈空间。
- 方法区:存储类的定义信息、静态变量和常量。方法区的大小可以通过JVM参数设置。
- PC寄存器:存储当前执行线程所指向的字节码指令。
内存溢出场景分析
内存溢出是指JVM的内存空间不足以满足应用程序的需求。常见的内存溢出场景包括:
- 堆内存溢出:创建大量对象,导致堆内存不足。
- 解决方案:通过调整JVM参数(如-Xmx)来增加堆内存大小,或者优化代码,减少对象创建。
- 栈内存溢出:递归调用过深,导致栈内存不足。
- 解决方案:优化代码,减少递归调用深度,或者使用尾递归优化。
- 方法区溢出:类定义过多或过大,导致方法区内存不足。
- 解决方案:优化代码,减少类定义数量和大小,或者使用轻量级类加载器。
垃圾回收
垃圾回收(GC)是JVM自动回收不再使用的对象占用的内存空间。垃圾回收过程包括以下几个关键概念:
- GC Roots可达性分析:从GC Roots开始,向上遍历可达对象,确定哪些对象是可达的。
- GC Roots:包括局部变量、线程栈、方法区等。
- 分代收集理论:将对象分为新生代(Young)、老年代(Old)和永久代(Perm),针对不同代采取不同的回收策略。
- 新生代:存放新创建的对象,垃圾回收频率高。
- 老年代:存放存活时间较长的对象,垃圾回收频率低。
- 永久代:存放静态数据,如类定义信息、静态变量等。
- 引用类型:包括强引用、软引用、弱引用和虚引用。
- 强引用:阻止垃圾回收器回收对象。
- 软引用:允许垃圾回收器在内存不足时回收对象。
- 弱引用:与软引用类似,但更易被回收。
- 虚引用:没有任何引用关系,仅用于跟踪对象的死亡。
- 垃圾回收算法:包括标记-清除、复制和整理算法。
- 标记-清除算法:首先标记所有可达对象,然后清除未标记的对象。
- 复制算法:将存活对象复制到另一半内存区域,并清空另一半。
- 整理算法:在复制算法的基础上,进行内存整理,提高内存利用率。
并发收集器
并发收集器在执行垃圾回收时,尽量减少对应用程序的干扰。常见的并发收集器包括CMS(Concurrent Mark Sweep)和G1(Garbage-First)。
- CMS(Concurrent Mark Sweep):一种以低停顿时间为目标的收集器,通过并发标记和清除阶段来减少停顿时间。
- G1(Garbage-First):一种以停顿时间预测为目标的收集器,通过将堆内存划分为多个区域,并优先回收垃圾回收价值最高的区域来减少停顿时间。
停顿时间控制策略
停顿时间控制策略旨在减少垃圾回收对应用程序的干扰。常见的策略包括:
- 并行GC:多线程并行执行垃圾回收,提高垃圾回收效率。
- 并发GC:与应用程序并发执行垃圾回收,减少停顿时间。
性能调优
性能调优是优化JVM性能的过程。常见的调优方法包括:
- JVM参数配置:通过设置JVM参数(如-Xms、-Xmx)来调整内存空间,以及设置垃圾回收策略等。
- 内存泄漏诊断:通过工具检测和修复内存泄漏。
- JVM监控工具:使用JVM监控工具(如JConsole、VisualVM)来监控JVM性能,找出性能瓶颈。
JIT编译优化
JIT(Just-In-Time)编译器是JVM的一个关键组件,它将字节码编译成本地机器码,以提高执行效率。JIT编译器的工作过程包括以下步骤:
- 热点检测:检测代码中的热点区域,即频繁执行的代码。
- 编译优化:对热点区域进行编译优化,生成高效的本地代码。
- 即时编译:将优化后的字节码编译成本地代码。
在深入探讨Spring Boot知识体系之前,我们先来了解一下Spring Boot的基本概念。Spring Boot是一个基于Spring框架的快速开发平台,它简化了Spring应用的初始搭建以及开发过程。以下是Spring Boot知识体系中的关键知识点:
自动配置
Spring Boot的自动配置功能可以自动配置Spring应用程序。以下是自动配置的关键概念:
- @EnableAutoConfiguration:通过该注解开启自动配置功能。它会根据项目依赖自动配置相关组件。
- 条件化配置:根据特定条件动态启用或禁用配置。例如,如果项目中包含了Redis依赖,则会自动配置Redis相关组件。
- 自定义Starter:创建自定义Starter以提供特定功能。例如,创建一个名为
my-starter的Starter,可以将常用的依赖打包在一起,方便其他项目使用。
起步依赖
起步依赖是Spring Boot提供的预定义依赖集合,用于简化依赖管理。起步依赖包括以下几类:
- Spring Web起步依赖:用于开发Web应用程序。
- Spring Data起步依赖:用于数据访问和操作。
- Spring Security起步依赖:用于安全控制。
- Spring Cloud起步依赖:用于构建微服务架构。
依赖管理机制
- BOM文件:用于定义项目依赖的版本。BOM文件可以确保项目中所有依赖的版本一致性。
- 版本冲突解决:通过BOM文件或依赖管理策略解决版本冲突。例如,使用Maven的
dependencyManagement配置来统一管理依赖版本。
第三方库集成
Spring Boot支持与第三方库的集成,例如数据库连接池、缓存框架等。集成第三方库可以通过以下方式:
- 依赖注入:使用Spring框架的依赖注入机制来集成第三方库。
- 配置文件:在配置文件中配置第三方库的参数。
- 注解:使用Spring框架的注解来配置第三方库。
Actuator
Spring Boot Actuator提供了一系列端点,用于监控和管理应用程序。以下是Actuator端点的一些常用功能:
- 健康检查端点:用于检查应用程序的健康状态。通过
/actuator/health端点可以获取应用程序的健康信息。 - 度量指标收集:用于收集应用程序的性能指标。通过
/actuator/metrics端点可以获取应用程序的度量指标。 - 自定义Endpoint:自定义端点以满足特定需求。通过实现
Endpoint接口并添加@RestController注解可以创建自定义端点。
配置文件管理
Spring Boot使用配置文件来管理应用程序的配置信息。以下是配置文件管理的一些关键概念:
- 多环境配置:通过配置文件(如
application-dev.yml、application-prod.yml)管理不同环境下的配置。 - 配置加载优先级:确定配置文件的加载顺序。Spring Boot会按照以下顺序加载配置文件:
file:./config/:应用程序的config目录。file:./:应用程序的根目录。classpath:/config/:类路径中的config目录。classpath:/:类路径的根目录。
- 动态配置刷新:实时更新配置信息。通过
spring.config活跃profile和spring.config应用两个配置项可以实现动态配置刷新。
监控与日志
Spring Boot提供了一系列监控和日志配置选项。以下是监控和日志配置的一些关键概念:
- Micrometer:用于集成各种监控工具。Micrometer支持多种监控工具,如Prometheus、Grafana等。
- Logback/SLF4J:用于配置日志框架。Spring Boot默认使用Logback作为日志框架,SLF4J作为日志门面。
分布式链路追踪
Spring Boot支持分布式链路追踪,例如Zipkin和Jaeger。分布式链路追踪可以帮助开发者追踪分布式系统中各个服务之间的调用关系,定位问题。
扩展机制
Spring Boot提供了多种扩展机制,例如:
- 自定义AutoConfigurationBean:自定义自动配置的Bean。通过实现
@Configuration注解的类,并添加@AutoConfigure注解可以自定义自动配置的Bean。 - 生命周期扩展点:自定义Bean的生命周期。Spring Boot提供了多种生命周期扩展点,如
@PostConstruct、@PreDestroy等。 - 响应式编程支持:支持响应式编程模型。Spring Boot支持响应式编程框架Reactor和Project Reactor。
通过以上对JVM和Spring Boot知识体系的详细描述,我们可以看到这两个技术之间的紧密联系。JVM作为Java平台的核心组件,为Spring Boot提供了运行环境。而Spring Boot则利用JVM的特性,简化了Java应用程序的开发过程。在实际应用中,深入理解这两个技术体系,可以帮助开发者更好地构建高性能、可维护的Java应用程序。
📥博主的人生感悟和目标
- 💂 博客主页: Java程序员廖志伟希望各位读者大大多多支持用心写文章的博主,现在时代变了,信息爆炸,酒香也怕巷子深,博主真的需要大家的帮助才能在这片海洋中继续发光发热,所以,赶紧动动你的小手,点波关注❤️,点波赞👍,点波收藏⭐,甚至点波评论✍️,都是对博主最好的支持和鼓励!
- 👉 开源项目: Java程序员廖志伟
- 🌥 哔哩哔哩: Java程序员廖志伟
- 🎏 个人社区: Java程序员廖志伟
- 🔖 个人微信号:
SeniorRD
📙经过多年在优快云创作上千篇文章的经验积累,我已经拥有了不错的写作技巧。同时,我还与清华大学出版社签下了四本书籍的合约,并将陆续出版。这些书籍包括了基础篇、进阶篇、架构篇的📌《Java项目实战—深入理解大型互联网企业通用技术》📌,以及📚《解密程序员的思维密码--沟通、演讲、思考的实践》📚。具体出版计划会根据实际情况进行调整,希望各位读者朋友能够多多支持!
🔔如果您需要转载或者搬运这篇文章的话,非常欢迎您私信我哦~

470

被折叠的 条评论
为什么被折叠?



