Java JVM & Spring Boot精讲

📕我是廖志伟,一名Java开发工程师、《Java项目实战——深入理解大型互联网企业通用技术》(基础篇)、(进阶篇)、(架构篇)清华大学出版社签约作家、Java领域优质创作者、CSDN博客专家、阿里云专家博主、51CTO专家博主、产品软文专业写手、技术文章评审老师、技术类问卷调查设计师、幕后大佬社区创始人、开源项目贡献者。

📘拥有多年一线研发和团队管理经验,研究过主流框架的底层源码(Spring、SpringBoot、SpringMVC、SpringCloud、Mybatis、Dubbo、Zookeeper),消息中间件底层架构原理(RabbitMQ、RocketMQ、Kafka)、Redis缓存、MySQL关系型数据库、 ElasticSearch全文搜索、MongoDB非关系型数据库、Apache ShardingSphere分库分表读写分离、设计模式、领域驱动DDD、Kubernetes容器编排等。不定期分享高并发、高可用、高性能、微服务、分布式、海量数据、性能调优、云原生、项目管理、产品思维、技术选型、架构设计、求职面试、副业思维、个人成长等内容。

Java程序员廖志伟

🌾阅读前,快速浏览目录和章节概览可帮助了解文章结构、内容和作者的重点。了解自己希望从中获得什么样的知识或经验是非常重要的。建议在阅读时做笔记、思考问题、自我提问,以加深理解和吸收知识。阅读结束后,反思和总结所学内容,并尝试应用到现实中,有助于深化理解和应用知识。与朋友或同事分享所读内容,讨论细节并获得反馈,也有助于加深对知识的理解和吸收。💡在这个美好的时刻,笔者不再啰嗦废话,现在毫不拖延地进入文章所要讨论的主题。接下来,我将为大家呈现正文内容。

CSDN

一、JVM知识体系

JVM(Java虚拟机)是Java语言运行时环境的核心,它不仅负责将Java代码编译成的字节码转换为机器码,还提供了丰富的运行时特性,如内存管理、线程管理等。以下是JVM知识体系中的关键知识点,并补充其技术实现细节。

类加载机制

类加载是JVM的一个重要机制,它负责将Java类编译成的字节码加载到JVM中。类加载过程包括以下几个阶段:

  1. 加载:查找并加载类的定义信息。在Java 9之后,类加载过程被进一步细分为几个子阶段,如查找、加载、链接和初始化。

    • 查找:通过类加载器查找类的定义信息,类加载器可以是系统类加载器、扩展类加载器或应用程序类加载器。
    • 加载:将类的定义信息载入到JVM中,包括类的字节码。
    • 链接:验证类信息,准备类变量,并解析符号引用。
    • 初始化:执行类的初始化代码,包括静态变量的赋值和静态代码块。
  2. 连接:连接阶段包括验证、准备和解析。

    • 验证:确保类的信息正确无误,包括字节码的格式、符号引用的合法性等。
    • 准备:为类变量分配内存,并设置初始值。
    • 解析:将符号引用转换为直接引用,如将类名解析为类的引用。
  3. 初始化:初始化阶段是执行类构造器<clinit>()的过程,它负责对类变量进行初始化和执行静态代码块。

双亲委派模型

双亲委派模型是JVM中的一种类加载策略,它要求除了顶层的启动类加载器外,其余的类加载器都应当有自己的父类加载器。当一个类加载器请求加载一个类时,它首先委派给父类加载器去加载,只有当父类加载器无法完成这个请求时,子类加载器才会尝试自己去加载。

这种模型的设计目的在于确保类型的安全,防止核心API被随意篡改。例如,java.lang包下的类默认由启动类加载器加载,而其他类则由应用程序类加载器或自定义类加载器加载。

自定义类加载器

自定义类加载器允许开发者控制类的加载过程,这在模块化系统(JPMS)中非常有用。开发者可以通过继承ClassLoader类或实现ClassLoader接口来创建自定义类加载器。

模块化系统(JPMS)

JPMS是Java 9引入的一种模块化系统,它允许开发者将代码划分为模块,并控制模块之间的依赖关系。模块化系统通过模块描述文件(module-info.java)来定义模块的名称、依赖和提供的接口。

内存模型

JVM的内存模型包括以下几个运行时数据区:

  1. :所有线程共享的内存区域,用于存放几乎所有的对象实例。堆空间是动态分配的,并且垃圾回收器主要在堆上进行回收。

    • 垃圾回收算法:包括标记-清除、复制、整理等算法。复制算法适用于新生代,标记-清除算法适用于老年代。
  2. :每个线程都有自己的栈,用于存放线程执行的字节码帧。栈空间是线程私有的,线程之间不会共享。

  3. 方法区:用于存储已经被虚拟机加载的类信息、常量、静态变量等数据。方法区是所有线程共享的。

  4. PC寄存器:每条线程都有一个程序计数器,用于指示下一条要执行的指令。程序计数器是线程私有的。

内存溢出场景分析

内存溢出通常发生在堆空间不足时,导致程序无法分配新的对象。常见的场景包括:

  • 创建大量对象:当创建的对象数量超过堆空间容量时,会引发OutOfMemoryError
  • 循环引用:当对象之间相互引用,且这些引用无法被垃圾回收器回收时,会引发内存泄漏。
  • 大对象内存分配:当分配的对象大小超过堆空间容量时,会引发OutOfMemoryError
垃圾回收

垃圾回收(GC)是JVM自动回收不再使用的对象所占用的内存。垃圾回收过程包括以下几个步骤:

  1. GC Roots可达性分析:从GC Roots开始,向上遍历可达性链,确定哪些对象是可达的。

    • GC Roots:包括栈帧中的局部变量表、静态变量、常量池等。
  2. 分代收集理论:将对象分为新生代(Young)、老年代(Old)和永久代(Perm),分别采用不同的回收策略。

    • 新生代:主要回收新生代中的对象,使用复制算法进行垃圾回收。
    • 老年代:主要回收老年代中的对象,使用标记-清除或标记-整理算法进行垃圾回收。
  3. 引用类型:根据引用的强度,对象可以分为强引用、软引用、弱引用和虚引用。

    • 强引用:最常用的引用类型,当对象被强引用时,垃圾回收器不会回收该对象。
    • 软引用:用于缓存对象,当内存不足时,垃圾回收器会回收软引用指向的对象。
    • 弱引用:类似于软引用,但垃圾回收器会尽快回收弱引用指向的对象。
    • 虚引用:用于跟踪对象被回收的情况,当对象被回收时,虚引用的引用对象会被置为null。
  4. 垃圾回收算法:包括标记-清除、复制、整理等算法。

    • 标记-清除:首先标记所有可达的对象,然后清除未被标记的对象。
    • 复制:将对象复制到其他区域,然后清理原区域。
    • 整理:将对象移动到一起,然后清理未使用的空间。
  5. 并发收集器:如CMS、G1、ZGC等,旨在减少停顿时间。

    • CMS(Concurrent Mark Sweep):一种并发标记清除垃圾回收器,旨在减少停顿时间。
    • G1(Garbage-First):一种并发标记整理垃圾回收器,旨在减少停顿时间。
    • ZGC(Z Garbage Collector):一种低延迟垃圾回收器,旨在减少停顿时间。
  6. 停顿时间控制策略:通过调整垃圾回收参数,控制垃圾回收的停顿时间。

    • G1:通过设置最大停顿时间来控制垃圾回收的停顿时间。
    • ZGC:通过设置最大停顿时间来控制垃圾回收的停顿时间。
性能调优

JVM性能调优涉及以下几个方面:

  1. JVM参数配置:通过设置参数如XmsXmx等来调整内存分配。

    • Xms:设置JVM启动时的堆空间大小。
    • Xmx:设置JVM最大堆空间大小。
  2. 内存泄漏诊断:使用工具如JProfiler、VisualVM等来诊断内存泄漏。

    • JProfiler:一款功能强大的性能分析工具,可以用于诊断内存泄漏。
    • VisualVM:一款轻量级的性能分析工具,可以用于诊断内存泄漏。
  3. JIT编译优化:JVM的即时编译器(JIT)对字节码进行优化,提高程序执行效率。

    • 编译优化:包括循环优化、内联优化、逃逸分析等。
    • 热点检测:JIT编译器会检测代码中的热点,并对热点进行优化。

二、Spring Boot知识体系

Spring Boot是Spring框架的一个模块,它简化了Spring应用的创建和配置过程。以下是Spring Boot知识体系中的关键知识点,并补充其技术实现细节。

自动配置

Spring Boot通过自动配置来简化应用配置。@EnableAutoConfiguration注解是自动配置的核心,它通过扫描类路径下的类和jar包,自动配置相应的Bean。

  1. 自动配置原理:Spring Boot自动配置依赖于条件化配置,即根据特定的条件自动配置Bean。

    • 条件化配置:通过@Conditional注解及其实现类,根据特定的条件自动配置Bean。
    • 条件注解:如@ConditionalOnClass@ConditionalOnMissingBean等。
  2. 自动配置条件:根据不同的条件自动配置相应的Bean。

    • 条件类路径:根据类路径下是否存在特定的类自动配置Bean。
    • 条件Bean:根据是否存在特定的Bean自动配置Bean。
    • 条件属性:根据配置文件中的属性值自动配置Bean。
@EnableAutoConfiguration原理

@EnableAutoConfiguration通过Spring的类路径扫描和自动配置机制,自动配置与项目相关的Bean。

  1. 类路径扫描:Spring Boot会扫描类路径下的类和jar包,查找带有@SpringBootApplication注解的类。
  2. 自动配置机制:Spring Boot会根据扫描到的类和jar包,自动配置相应的Bean。
条件化配置(@Conditional)

条件化配置允许在满足特定条件时才配置Bean。

  1. 条件注解:如@ConditionalOnClass@ConditionalOnMissingBean等。

    • @ConditionalOnClass:当类路径下存在特定的类时,自动配置Bean。
    • @ConditionalOnMissingBean:当不存在特定的Bean时,自动配置Bean。
  2. 条件实现类:实现Condition接口的类,根据特定的条件自动配置Bean。

自定义Starter开发

自定义Starter可以简化依赖管理,提高项目的可重用性。

  1. 创建Starter:创建一个包含所有必需依赖的jar包。
  2. 添加依赖:在Starter的pom.xml文件中添加所有必需的依赖。
  3. 添加自动配置:在Starter中添加自动配置类,自动配置与Starter相关的Bean。
起步依赖

起步依赖是Spring Boot提供的依赖管理方式,它将所有必需的依赖打包成一个jar包。

  1. 起步依赖:在pom.xml文件中添加起步依赖,如spring-boot-starter-web
  2. 依赖管理:Spring Boot会自动管理起步依赖中的所有依赖。
依赖管理机制(BOM文件)

BOM(Bill of Materials)文件用于定义项目依赖的版本,确保所有依赖的一致性。

  1. BOM文件:在pom.xml文件中添加BOM文件,如<dependencyManagement>标签。
  2. 依赖版本:BOM文件定义了所有依赖的版本,确保项目中的所有依赖使用相同的版本。
版本冲突解决

版本冲突是依赖管理中的常见问题,可以通过选择兼容的版本或使用依赖冲突解决策略来解决。

  1. 选择兼容版本:选择兼容的版本,避免版本冲突。
  2. 依赖冲突解决策略:使用Maven或Gradle的依赖冲突解决策略,如<dependencyManagement>标签或dependencyConflictResolver插件。
第三方库集成模式

Spring Boot支持多种第三方库的集成模式,包括自动配置、配置文件等。

  1. 自动配置:使用自动配置类自动配置第三方库。
  2. 配置文件:在配置文件中配置第三方库的参数。
Actuator

Actuator是Spring Boot提供的模块,它提供了健康检查、度量指标收集等功能。

  1. 健康检查:通过/actuator/health端点检查应用的运行状态。
  2. 度量指标收集:通过/actuator/metrics端点收集应用的度量指标。
健康检查端点

健康检查端点允许开发者检查应用的运行状态。

  1. 端点/actuator/health端点。
  2. 返回值:返回应用的运行状态,包括健康状态、详细信息等。
度量指标收集

度量指标收集可以帮助开发者了解应用的性能和资源使用情况。

  1. 端点/actuator/metrics端点。
  2. 度量指标:包括内存使用、CPU使用、线程数等。
自定义Endpoint开发

自定义Endpoint允许开发者添加自定义的端点,提供额外的监控信息。

  1. 实现Endpoint接口:实现Endpoint接口,定义自定义端点的行为。
  2. 注册Endpoint:将自定义端点注册到Spring Boot中。
配置文件管理

Spring Boot使用配置文件来管理应用配置,支持多环境配置。

  1. 配置文件application.propertiesapplication.yml
  2. 多环境配置application-{profile}.propertiesapplication-{profile}.yml
多环境配置(application-{profile}.yml)

多环境配置允许开发者为不同的环境(如开发、测试、生产)配置不同的参数。

  1. 配置文件application-dev.ymlapplication-test.ymlapplication-prod.yml
  2. 配置覆盖:当多个配置文件存在时,配置文件之间的配置会进行覆盖。
配置加载优先级

配置加载优先级决定了配置文件之间的配置覆盖关系。

  1. 优先级:配置文件越靠近项目根目录,优先级越高。
  2. 覆盖关系:当多个配置文件存在时,配置文件之间的配置会进行覆盖。
动态配置刷新

动态配置刷新允许在应用运行时更新配置。

  1. 端点/actuator/refresh端点。
  2. 配置更新:通过端点发送POST请求,更新配置。
监控与日志

Spring Boot提供监控和日志功能,可以帮助开发者监控应用和调试问题。

  1. 监控:通过Actuator模块进行监控。
  2. 日志:通过Logback或SLF4J进行日志管理。
Micrometer集成

Micrometer是Spring Boot提供的度量指标收集工具,可以集成多种监控系统。

  1. 监控系统:如Prometheus、Grafana等。
  2. 度量指标:包括内存使用、CPU使用、线程数等。
Logback/SLF4J配置

Spring Boot默认使用Logback作为日志框架,也支持SLF4J。

  1. Logback:一款功能强大的日志框架,可以用于日志管理。
  2. SLF4J:一款日志门面,可以将日志输出到不同的日志框架。
分布式链路追踪

Spring Boot支持分布式链路追踪,如Zipkin、Skywalking等。

  1. Zipkin:一款开源的分布式追踪系统。
  2. Skywalking:一款开源的分布式追踪系统。
扩展机制

Spring Boot提供扩展机制,允许开发者添加自定义的AutoConfiguration、Bean等。

  1. 自定义AutoConfiguration:实现AutoConfigure接口,添加自定义的自动配置。
  2. 自定义Bean:通过@Bean注解,添加自定义的Bean。
自定义AutoConfigurationBean生命周期扩展点

自定义AutoConfigurationBean的生命周期扩展点允许开发者控制Bean的创建和销毁。

  1. 生命周期扩展点:如@PostConstruct@PreDestroy等注解。
  2. Bean创建和销毁:在Bean的创建和销毁过程中,执行特定的操作。
响应式编程支持

Spring Boot支持响应式编程,可以通过Spring WebFlux等模块实现。

  1. 响应式编程:使用响应式编程框架,如Reactor、Project Reactor等。
  2. Spring WebFlux:Spring Boot的响应式Web框架。

通过以上知识点的串联,我们可以看到JVM和Spring Boot在Java应用开发中扮演着至关重要的角色。JVM负责Java代码的执行环境,而Spring Boot则提供了快速开发Spring应用的框架。理解这两个知识体系,可以帮助开发者更好地构建和维护高性能、可扩展的Java应用。

CSDN

📥博主的人生感悟和目标

Java程序员廖志伟

希望各位读者大大多多支持用心写文章的博主,现在时代变了,信息爆炸,酒香也怕巷子深,博主真的需要大家的帮助才能在这片海洋中继续发光发热,所以,赶紧动动你的小手,点波关注❤️,点波赞👍,点波收藏⭐,甚至点波评论✍️,都是对博主最好的支持和鼓励!

- 💂 博客主页Java程序员廖志伟
- 👉 开源项目Java程序员廖志伟
- 🌥 哔哩哔哩Java程序员廖志伟
- 🎏 个人社区Java程序员廖志伟
- 🔖 个人微信号SeniorRD

Java程序员廖志伟

📙经过多年在CSDN创作上千篇文章的经验积累,我已经拥有了不错的写作技巧。同时,我还与清华大学出版社签下了四本书籍的合约,并将陆续出版。这些书籍包括了基础篇进阶篇、架构篇的📌《Java项目实战—深入理解大型互联网企业通用技术》📌,以及📚《解密程序员的思维密码--沟通、演讲、思考的实践》📚。具体出版计划会根据实际情况进行调整,希望各位读者朋友能够多多支持!

🔔如果您需要转载或者搬运这篇文章的话,非常欢迎您私信我哦~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值