JAVA

Java 技术

深入解析 Java、JVM、Spring、并发编程与服务端工程实践。

24 篇文章

HotSpot C2 自动向量化:Superword 算法如何将循环转换为 SIMD 指令

为什么有的循环能被 JVM 自动向量化,有的却不能?本文以数组求和与元素变换为贯穿场景,剖析 HotSpot C2 编译器 Superword 算法的基本步骤,解释循环展开、内存对齐、无别名等关键条件,并给出编写可向量化代码的实用指导,同时对比自动向量化与手写 SIMD 的权衡。

Spring @Cacheable 的 sync 属性:缓存击穿下的同步加载与锁竞争

本文深入解读 Spring @Cacheable 的 sync 属性如何通过同步控制防止缓存击穿,重点分析在高并发下 sync=true 为何可能导致锁竞争,以及如何与 Redis 等缓存提供者的原子操作配合。通过热点数据过期场景,读者将理解 Spring Cache 拦截器的同步机制、不同缓存提供者的锁实现,以及通过自定义 CacheErrorHandler 处理异常,从而获得避免缓存击穿和锁问题的配置方法。

Spring @Async 线程池拒绝策略:CallerRunsPolicy 下的上下文传播与死锁风险

本文剖析 Spring @Async 默认线程池的拒绝策略,重点讨论 CallerRunsPolicy 在任务堆积时如何导致调用线程阻塞、上下文丢失甚至死锁。通过一个高并发异步任务堆积的贯穿场景,解释 ThreadPoolTaskExecutor 的配置与拒绝策略行为,并给出自定义拒绝策略和上下文传播的解决方案,帮助读者根据任务特性选择合适的拒绝策略。

HotSpot C2 方法内联的决策机制:阈值、调用深度与去虚拟化

本文分析 HotSpot C2 编译器如何根据方法大小、调用频率和调用深度决定内联,解释为何某些热点方法未被内联,并演示如何通过 -XX:MaxInlineSize 等参数优化。以微服务中频繁调用的工具方法为贯穿场景,介绍内联收益与成本、虚方法去虚拟化技术,以及使用 -XX:+PrintInlining 诊断内联失败的方法,帮助读者平衡编译时间与运行时性能。

Shenandoah GC 并发疏散与 Brooks 指针:如何在不暂停应用的情况下移动对象

Shenandoah GC 通过并发疏散机制将对象移动与 Java 线程并行执行,从而将停顿时间控制在亚毫秒级。本文聚焦 Brooks 指针与读屏障如何实现“移动对象时不暂停应用线程”这一核心问题,以高并发 Web 服务在大型堆下的停顿优化为场景,逐步展开并发标记、并发疏散、引用更新等阶段的工程细节,并与 ZGC 进行对比,为读者提供吞吐与延迟之间权衡的决策依据。

JVM 分层编译的层级选择:C1/C2 编译器协作与预热期性能优化

分析 HotSpot 分层编译的五个执行层级,解释为何方法在 C1 编译后可能被 C2 重新编译,以及如何通过 -XX:TieredStopAtLevel 控制编译策略。以微服务启动后预热期的性能抖动为贯穿场景,讨论编译阈值、Profiling 数据收集、去优化机制,并与 Graal JIT 进行对比。读者将掌握根据延迟和吞吐需求调整编译层级的参数,并理解为何短生命周期方法不适合 C2 编译。

Java 模块系统分裂包问题:JPMS 中的包冲突与模块路径解析

当多个模块导出同名包时,JPMS 会因分裂包而拒绝启动。本文以大型应用从类路径迁移到模块路径为场景,解释模块解析过程中包唯一性约束的由来,剖析导致分裂包的常见依赖结构,并给出通过模块描述符、构建工具及命令行选项诊断与修复问题的具体步骤。

类加载器泄漏:Spring Boot 热部署与多模块应用中的元空间溢出

本文分析 Java 类加载器泄漏的典型模式,以 Spring Boot DevTools 频繁重启为贯穿场景,解释元空间持续增长直至 OOM 的根本原因。文章梳理类加载器引用链、ThreadLocal 残留、静态字段持有等关键泄漏路径,并结合 Eclipse Memory Analyzer 演示诊断步骤。读者将掌握识别和修复类加载器泄漏的方法,理解为何关闭线程池和清除上下文是防止泄漏的核心措施。

Spring @Transactional 传播行为与隔离级别的交互陷阱:订单创建与库存扣减中的幻读与死锁

本文剖析 Spring 声明式事务中传播行为(特别是 REQUIRES_NEW)与数据库隔离级别的组合效应。通过订单创建与库存扣减的跨服务事务编排场景,解释 Spring 事务管理器如何映射传播行为到 JDBC 连接、保存点与事务同步,并分析不同隔离级别下的锁行为与异常路径。读者将获得避免事务边界错误和性能问题的决策矩阵,并理解为何默认隔离级别可能不适用于高并发写操作。

偏向锁的撤销与废弃:从 JEP 374 看同步优化演进

本文分析偏向锁在 Java 15 中被默认禁用并最终移除的工程原因,聚焦高并发下撤销开销如何抵消收益。以线程池频繁争用的同步块性能诊断为贯穿场景,解释偏向锁的获取、撤销、批量重偏向与批量撤销流程,并结合 JEP 374 的决策依据,说明现代应用为何应避免依赖偏向锁,以及如何通过 JFR 和锁分析工具诊断同步性能。

G1 GC 区域化内存管理与记忆集的工程权衡

本文聚焦 G1 GC 如何通过区域划分和记忆集实现并发标记与部分回收,核心问题是“在低延迟目标下,记忆集维护如何影响吞吐与内存开销”。以高并发订单服务为贯穿场景,分析记忆集数据结构、写屏障、SATB 算法及调优参数,并与 CMS 和 ZGC 对比,帮助读者根据堆大小和延迟目标选择 GC 策略。

JFR 事件流与持续监控:基于 JDK Flight Recorder 的零侵入观测

本文深入解析 JDK Flight Recorder 的事件流 API 如何实现生产环境下的低开销实时监控。通过一个高并发交易服务的贯穿场景,阐述事件流的内部架构、关键事件类型、与 Prometheus 等外部系统的集成方式,以及锁竞争、内存分配等细节的采集原理。文章还对比了传统 JMX 监控的局限,并讨论虚拟线程下的 pinning 检测、背压控制等常见失败模式,为构建自定义预警提供工程指导。

AppCDS 与类数据共享:JVM 启动提速的内部机制

本文深入解读类数据共享(CDS)与应用类数据共享(AppCDS)的内存映射原理,通过一个多实例微服务场景贯穿全文,回答如何有效降低多实例环境下的内存占用与启动时间。文章基于 JEP 310、JEP 350 及官方文档,详细说明共享归档的生成、使用、动态归档机制、常见失败模式及调优指南,并提供与替代方案的对比。

Spring AOT 引擎如何通过封闭世界假设处理反射与动态代理

本文分析 Spring AOT 引擎在 GraalVM 原生镜像构建中的核心机制,聚焦封闭世界假设下反射与动态代理的处理方式。通过一个订单查询微服务场景,贯穿静态分析、代理注册、配置提示和编译流程,并与 JVM 模式进行定性比较,帮助读者理解 Spring 原生镜像在启动耗时与内存占用上的优化原理及适用边界。