📕我是廖志伟,一名Java开发工程师、《Java项目实战——深入理解大型互联网企业通用技术》(基础篇)、(进阶篇)、(架构篇)清华大学出版社签约作家、Java领域优质创作者、CSDN博客专家、阿里云专家博主、51CTO专家博主、产品软文专业写手、技术文章评审老师、技术类问卷调查设计师、幕后大佬社区创始人、开源项目贡献者。
📘拥有多年一线研发和团队管理经验,研究过主流框架的底层源码(Spring、SpringBoot、SpringMVC、SpringCloud、Mybatis、Dubbo、Zookeeper),消息中间件底层架构原理(RabbitMQ、RocketMQ、Kafka)、Redis缓存、MySQL关系型数据库、 ElasticSearch全文搜索、MongoDB非关系型数据库、Apache ShardingSphere分库分表读写分离、设计模式、领域驱动DDD、Kubernetes容器编排等。不定期分享高并发、高可用、高性能、微服务、分布式、海量数据、性能调优、云原生、项目管理、产品思维、技术选型、架构设计、求职面试、副业思维、个人成长等内容。

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

JVM知识体系补充说明
类加载机制
在类加载机制中,加载(Loading)阶段不仅仅是简单的文件读取,它涉及到类文件的字节码读取、符号引用的解析和类的定义数据结构的初始化。具体实现上,JVM使用类加载器(ClassLoader)来负责这一过程。Java中的类加载器分为启动类加载器(Bootstrap ClassLoader)、扩展类加载器(Extension ClassLoader)和应用类加载器(Application ClassLoader),以及用户自定义类加载器。
- 启动类加载器:负责加载
<JAVA_HOME>/lib
目录(或由-Xbootclasspath
参数指定的路径)中的,或由系统库路径所指定的jar文件中的类库。 - 扩展类加载器:负责加载
<JAVA_HOME>/lib/ext
目录中的,或由系统变量java.ext.dirs
指定的路径中的jar包。 - 应用类加载器:负责加载用户类路径(ClassPath)上的所有类库。
在连接(Linking)阶段,JVM会进行验证、准备和解析三个子过程。验证确保类文件字节码的有效性,准备阶段为静态变量分配内存并设置默认初始值,解析阶段将符号引用转换为直接引用。
类加载过程
双亲委派模型(Parent Delegation Model)是一种安全机制,确保了类加载的层次结构和隔离性。在自定义类加载器时,可以通过覆写findClass
方法来实现特定的类加载逻辑。例如,可以通过网络动态加载类,或者实现不同的类加载逻辑以满足特定的业务需求。
Java 9引入的模块化系统(JPMS)则进一步增强了类加载的安全性、可扩展性和性能。模块化系统允许开发者将应用程序分解成多个模块,每个模块都包含自己的类路径、资源路径和服务路径,从而提高了应用程序的可维护性和安全性。
内存模型
堆(Heap)是JVM中最大的内存区域,用于存储所有类的实例和数组的对象。堆内存的分配和回收是垃圾回收器(Garbage Collector, GC)的主要工作内容。栈(Stack)是线程私有的内存区域,用于存储局部变量和方法调用。方法区(Method Area)存储已被虚拟机加载的类信息、常量、静态变量等数据,它的大小通常比堆小,但同样受到限制。
在内存溢出场景分析中,堆溢出通常是由于应用程序创建了过多的对象,或者对象生命周期过长导致的。栈溢出则可能是由于递归调用深度过大或者方法栈大小限制不足引起的。方法区溢出可能是因为加载了过多的类或者类定义过大。
垃圾回收
垃圾回收(GC)是一个复杂的主题,它涉及多个算法和策略。GC Roots可达性分析是垃圾回收的核心,它通过遍历GC Roots找到所有可达的对象,并标记为存活状态。分代收集理论将对象分为年轻代和老年代,年轻代使用复制算法,而老年代则可能使用标记-清除、标记-整理或混合算法。
引用类型在垃圾回收中扮演着重要角色。强引用是最常见的引用类型,它阻止垃圾回收器回收被强引用的对象。软引用和弱引用允许垃圾回收器在内存不足时回收被这些引用的对象。虚引用则是一个指向对象的弱引用,它唯一的作用是当对象被回收时,通过虚引用的引用队列可以得知。
性能调优
JVM性能调优是一个系统工程,需要综合考虑内存、CPU、I/O等多个方面。JVM参数配置是性能调优的第一步,通过调整堆内存大小(-Xms
和-Xmx
)、新生代和老年代的比例(-XX:NewRatio
和-XX:MaxNewSize
)、垃圾回收策略(-XX:+UseG1GC
等)等参数,可以优化JVM的性能。
内存泄漏诊断是性能调优的重要环节。通过分析堆转储文件(Heap Dump)和线程转储文件(Thread Dump),可以发现内存泄漏的根源。JIT编译优化则是通过编译器优化字节码,提高程序执行效率。
Spring Boot知识体系补充说明
自动配置
Spring Boot的自动配置依赖于条件化配置(@Conditional)注解。当使用@EnableAutoConfiguration
注解时,Spring Boot会根据项目依赖自动配置相应的Bean。例如,如果项目中存在Spring Data JPA的依赖,Spring Boot会自动配置EntityManagerFactory
、TransactionManager
等Bean。
在自定义Starter开发中,开发者需要创建一个Maven项目,并在pom.xml
中添加Spring Boot的起步依赖。通过在META-INF/spring.factories
文件中添加自动配置的类路径,可以实现自定义Starter的自动配置。
配置文件管理
Spring Boot使用YAML或Properties格式的配置文件来管理应用程序的配置。多环境配置通过在文件名中添加环境标识(如application-dev.yml
和application-prod.yml
)来实现。配置加载优先级由配置文件的路径和文件名决定,文件名中环境标识越靠前,优先级越高。
动态配置刷新是通过Spring Cloud Config和Spring Cloud Bus实现的。Spring Cloud Config提供集中式的配置管理服务,而Spring Cloud Bus则允许动态刷新分布式系统中的配置。
监控与日志
Spring Boot Actuator提供了一系列端点,如/health
、/metrics
、/info
等,用于监控和管理应用程序。健康检查端点可以通过实现@HealthIndicator
接口来自定义健康检查逻辑。度量指标收集可以通过集成Micrometer来实现,它支持多种度量收集器。
自定义Endpoint开发可以通过实现Endpoint
接口和@Endpoint
注解来实现。这些自定义端点可以提供额外的监控和管理功能。
分布式链路追踪
Spring Boot支持分布式链路追踪,如Zipkin和Jaeger。通过集成这些工具,可以在分布式系统中追踪请求的执行路径。自定义AutoConfigurationBean生命周期扩展点可以通过实现AutoConfigurationImportBeanPostProcessor
接口来实现,从而在自动配置过程中添加自定义逻辑。
响应式编程支持是通过Spring WebFlux实现的,它允许以非阻塞的方式处理HTTP请求。通过@SpringBootApplication
注解,可以启用响应式支持,并在应用程序中注入Mono
和Flux
等响应式类型。
通过以上对JVM和Spring Boot知识体系的详细描述,我们可以看到这两个技术在实际应用中的紧密联系。JVM为Java应用程序提供了运行环境,而Spring Boot则简化了Spring应用程序的开发和部署。在实际开发中,理解JVM的工作原理和Spring Boot的特性对于优化应用程序性能和开发效率至关重要。
📥博主的人生感悟和目标

- 💂 博客主页: Java程序员廖志伟希望各位读者大大多多支持用心写文章的博主,现在时代变了,信息爆炸,酒香也怕巷子深,博主真的需要大家的帮助才能在这片海洋中继续发光发热,所以,赶紧动动你的小手,点波关注❤️,点波赞👍,点波收藏⭐,甚至点波评论✍️,都是对博主最好的支持和鼓励!
- 👉 开源项目: Java程序员廖志伟
- 🌥 哔哩哔哩: Java程序员廖志伟
- 🎏 个人社区: Java程序员廖志伟
- 🔖 个人微信号:
SeniorRD

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