“冰山”梗是一种网络现象,幽默而有时令人不安地展示了某个主题的知识或入门层次——从冰山之巅简单、广为人知的常识到只有最坚韧的老兵才能理解的黑暗、神秘深处。想象一座海洋上矗立的冰山:表面可见的部分只是开始,真正的魔法(或噩梦)隐藏在越来越难以触及的深渊。
冰山之巅
在这个阶段,你就像刚安装JDK的新手,认为“Hello World”是编程成就的顶峰,而你最大的戏剧性事件是某行代码末尾的分号缺失。
与此同时,你开始注意到那些“专业人士”谈论的技术,每项都像进入某种神秘知识的新阶段。
Spring Boot
Spring Boot 像是经典 Spring 的精简版。使用传统 Spring 时,你得到一个工具箱,需要自己组装所有东西,就像没有说明书地拼乐高。Boot 的创建是为了简化这个过程——不再需要手动接线,只需开箱即用。
“对速度的需求”促成了它的诞生。经典 Spring 虽强大但配置缓慢,让简单任务变得令人沮丧。2014 年,Pivotal 推出 Boot 自动化配置,让开发者专注于编码而非繁琐设置。它仍是 Spring,只是更省心。
Quarkus
Quarkus 应运而生,旨在解决在 GraalVM 和 Kubernetes 上运行敏捷工具的需求,而老旧的 Java 框架则像恐龙一样步履蹒跚。Quarkus 保持轻巧敏捷,完美适配微服务和无服务器架构——摒弃了臃肿的冗余。不同于资源密集型框架,它将繁重工作转移到构建阶段,快速启动且轻盈,并配备流畅的“Dev Mode”以保持编码顺畅。
由 Red Hat 发起,在其监管下迅速崛起,2024 年跳槽至 Commonhaus 基金会,加入更广泛的团队继续震撼 Java 世界。
Micronaut
与之前的两个类似,一个 Micronaut Java 项目作为一个框架出现,专为构建灵活、高性能的应用程序而设计,特别适合微服务和无服务器设置。它的创建由 Graeme Rocher 领导,他是 Grails 框架的共同创建者,将他们的专业知识投入到重新思考 Java 的潜力中。与过去那些笨重、依赖反射的 Java 框架不同,Micronaut 通过提前编译(AOT)来颠覆传统,大幅减少了启动延迟并消除了内存膨胀。Micronaut 与 GraalVM 无缝集成,并且可以被视为该技术的“官方”解决方案。
Lombok
Project Lombok 是一个工具,它让开发者从编写获取器、设置器和构造函数的令人心力交瘁的重复劳动中解脱出来,直到他们的手指都流血为止。通过像 @Data 或 @Getter 这样的注解,它轻声对编译器说:“嘿,让我们在幕后生成那些样板代码吧,”让你的代码看起来既时尚又优雅。简单来说,它让 Java 开发者摆脱了 Kotlin 的羡慕。
当然,一些纯粹主义者抱怨这就像是在你的代码库中释放一个巫师,启动“魔法”,并可能让调试变成寻宝游戏,但如今大多数人只是享受这个过程。
光合作用带
在这里,你开始意识到 Java 不仅仅是编写代码——它也是关于类路径的战斗,仿佛你正在扮演一位考古学家寻找失落文物。你已经遇到了 NullPointerException,并开始怀疑这不是巧合,而是 Java 对你试图理解原本应该保持隐藏的事物的一种报复。
Java 21 features
在许多人仍在生产环境中使用 JDK 1.8 的时代,去年发布的 Java 21 引入了如此丰富的特性,其发布反响超出了通常的 JVM 爱好者圈子。最受期待的添加之一是虚拟线程,它彻底改变了 Java 中的并发编程。这些轻量级线程允许开发人员更高效地创建和管理线程,通过将 Java 线程与操作系统线程解耦,虚拟线程能够处理大量并发任务,而无需传统线程管理带来的开销。
Java 21 中的另一个重要增强是 switch 语句的模式匹配功能。这项功能支持对各种数据类型进行更优雅、更易读的操作,使开发人员能够编写简洁且类型安全的代码,同时避免过多的类型转换和复杂的条件结构。此外,记录模式的引入简化了对象的解构,优化了数据处理并提高了代码清晰度。
Jakarta EE
Jakarta EE 的第一个版本,当时被称为 Java EE,于 1999 年 12 月发布,为基于 Java 的企业应用程序带来了标准。在接下来的几年里,该平台不断发展,随着 servlets、Java Server Pages(JSP)和企业 JavaBeans(EJB)等技术的引入而广受欢迎。
是的,这曾经真正让社区兴奋不已。
2017 年,Oracle 宣布将 Java EE 开源给 Eclipse 基金会。由于与“Java”这个名字相关的法律问题——这是一个商标——该平台的新版本被更名为 Jakarta EE。在新名称下的第一个发布版本 Jakarta EE 8 于 2019 年 9 月发布,并与 Java EE 8 完全兼容,为开发者提供了平稳的过渡。后续版本,如 2020 年的 Jakarta EE 9,引入了重大变化,包括将命名空间从“javax”迁移到“jakarta”。最新版本 Jakarta EE 10 于 2022 年 9 月发布——尽管在本书出版时,我们本应已经享受到了 Jakarta EE 11。
Helidon
与 Micronaut 或 Quarkus 类似,Helidon 作为一个现代 Java 框架脱颖而出,特别适用于微服务和云原生环境。由 Oracle 自身创建,它提供两种不同风格:Helidon SE(独立版本),以及与 MicroProfile 项目保持一致的 Helidon MP。Helidon 与 GraalVM 等工具无缝集成,并在 Docker 等容器化环境中表现优异。
然而,Helidon 生态系统中最有趣的部分是 Helidon Níma。基于 Java 的 Project Loom 及其虚拟线程构建,Níma 通过用轻量级、可扩展的模型取代旧的每个请求一个线程的方法来重新定义并发,轻松处理数千个任务。这使得它是 Helidon 拼图中最令人兴奋的部分,提供闪电般的性能和精简的内存占用,非常适合高并发的微服务,并证明 Helidon 不仅与时俱进,而且正在将 Java 推向未来。
GraalVM
如寻宝者追寻宝藏一样,GraalVM 在 Java 领域崛起为一股强大力量,由 Oracle 之手打造,为微服务和云原生构造的土地实现高性能。它是一个通用引擎,不仅服务于 Java,更以提前编译(AOT)的技艺点燃 Java,将字节码转化为原生可执行文件。与 Helidon 和 Quarkus 等可靠工具为伴,在 Docker 的容器中蓬勃发展,GraalVM 确实消除了启动延迟,减轻了内存负担。
然而,GraalVM 领域最令人惊叹的奇迹在于其原生镜像的精巧。通过将 Java源码铸造成单一二进制文件,它摆脱了普通 JVM 沉重的负担,赋予其风驰电掣的速度和吝啬者宝藏般微小的足迹。这使其成为 GraalVM 谜题中最激动人心的部分,适合微服务和无服务器工作,展示出 GraalVM 不仅满足当前需求的速度,更重新定义了 Java 在科技变革中的命运。
现代 Java 垃圾收集器
其中广泛讨论之一的是 JDK 11 中引入的 ZGC。ZGC 专为需要最小中断的应用设计,即使在多 GB 内存堆的情况下也能提供毫秒级的暂停。ZGC 的关键创新之一是使用所谓的“彩色指针”,这使得在不要求应用线程长时间暂停的情况下,能够高效地跟踪内存中的对象。
另一个垃圾回收器是 Shenandoah,它也出现在 JDK 11 附近,并且以单一目标开发——最小化延迟。像 ZGC 一样,Shenandoah 以并发方式运行,但以其堆压缩方法脱颖而出,该方法在不停止应用程序的情况下执行。这个过程在较旧的 GC(如 CMS 或 G1)中传统上会导致显著的暂停。
中层带
在这个领域,光线渐暗,项目名称听起来像是被遗忘的古老神的名字(瓦尔哈拉,对吧)。你感觉自己走在疯狂边缘,代码中涌动着生命,似乎守护着隐藏的秘密。黑暗中有什么在注视着你,有什么知道一切。
Project Valhalla
项目 Valhalla 于 2014 年启动,是 Java 为解决其性能问题和修复原始对象分裂所做的雄心勃勃的尝试。它包含了 ValueClasses——可以理解为精简的、无身份标识的数据类型,摒弃了 Object 的开销,直接内联存储在内存中以减少堆内存使用和 GC 开销。还有 Primitive Classes,改进了 int、double 等类型,使其在泛型中能更好地配合使用。再加上Specialization的加入,泛型不再被擦除为 Object,而是获得自定义的、类型特定的字节码。回报是什么?更紧凑的内存布局,更少的缓存未命中,以及在现代硬件上高效运行的虚拟机。
但问题是:十年过去了,Valhalla 依然没有兑现承诺。它陷入了技术泥潭——升级 JVM、保持字节码兼容性,还要重构老旧的类型系统而不引发骚乱。早期的草案(JEPs 401、402)和测试版本让我们垂涎,但终点线却不断后移。这是一场在向后兼容的地狱和边缘案例的噩梦中的挣扎,所有这一切都是为了使 Java 成为更适合数据处理工作负载的更精干、更强大的野兽。
Project Lilliput
2021 年,Red Hat 公司的 Roman Kennke 发起了 Lilliput 项目,旨在将 HotSpot JVM 中的对象头大小从 128 位减少到 64 位,甚至可能减少到 32 位。在 64 位的 HotSpot JVM 中,每个对象包含一个 64 位的“标记字”(用于同步和哈希码)以及一个 64 位的类指针——对于小对象(通常为 5-6 个词),这个头部构成了显著的额外开销。Lilliput 项目引入了紧凑对象头(JEP 450),通过将类元数据移至单独结构并优化锁管理,将对象头重构为 64 位。这一改进带来了切实的效益,包括减少堆内存使用、降低垃圾回收频率以及提高 CPU 缓存利用率。
与永远被推迟的 Project Valhalla 不同,Project Lilliput 已经兑现了它的承诺。JEP 450 已集成到 JDK 24(将于 2025 年 3 月发布)中作为一项实验性功能,并持续努力进一步将头部压缩到 32 位。主要挑战包括保持与现有 JVM 代码的兼容性、优化轻量级锁定机制,以及尝试进一步压缩技术。结果是更精简的 Java 内存占用,未来还有更高的效率前景,这一次没有无尽的延迟。
Spring AI、Langchain4j、SEMANTIC Kernel
让我们深入Spring AI、LangChain4j和Semantic Kernel的奇妙世界-这三个 Java 框架是 AI 爱好者的最佳组合。
Spring AI 是 Spring 生态系统的一部分,大摇大摆地登场,致力于为你的 Java 应用撒上 AI 魔法。它专注于将基础模型和向量存储包裹在舒适的 Spring Boot 自动配置中,并提供时尚的 API 用于与模型交互,同时支持 RAG(检索增强生成)以提供更智能的答案。
与此同时,LangChain4j 就像一个顽强的独立少年,将 Python LangChain 的风格移植到 Java 上,还带着“我们不需要什么该死的 Python”的态度。它拥有 AIServices——可以理解为隐藏 LLM 底层架构的声明式接口——以及用于内存、嵌入和提示链的工具。
然后还有语义内核(Semantic Kernel),这是微软参与这场竞争的产物,支持 Java、C#和 Python。它同样是在 2023 年推出的,有着多智能体系统的宏伟目标,但其 Java 支持与 Python 团队相比,感觉还只是在做热身练习。
Spring Modulith
Spring Modulith 是 Spring 生态系统中的一个巧妙小工具,帮助您将 Spring Boot 项目整理成整洁、模块化的模块。凭借结构验证和保持松散耦合的规则集,它帮助将单体应用转变为可维护的项目,而无需强迫您加入微服务的大军。非常适合希望保持简单且可扩展的开发者。
JBang
JBang 是一个简化运行、管理和创建 Java 脚本(有意为之)的工具,无需传统的、重量级的项目设置。它允许开发者像执行 shell 脚本一样轻松执行 Java 代码,通过一次性下载依赖项、编译和运行代码来实现——所有操作都通过一个命令完成。
使用 JBang,你可以编写一个 Java 文件,通过简单的注释(如 //DEPS )包含依赖,并使用 jbang script.java 立即运行它,这使得它在原型设计、脚本编写或构建小型工具方面非常理想。
深层带
在这里,你完全失去了时间感,仅仅是理解这些倡议为何被启动本身就感觉像是一项挑战。深度压得你几乎窒息,但你却无法停止下沉——有什么东西在呼唤你,某种更接近知识本质(以及虚拟机)的东西,而不是又一个 CRUD。
jSpecify
这项倡议旨在规范 Java 中的空值性注解,提供一套一致的注解,使静态代码分析能够识别潜在的 NullPointerException 问题,从而减少此类错误。
2024 年 7 月,jSpecify 项目发布了 1.0 版本。该项目引入了四个关键注解:
- @Nullable: 表示变量、参数或返回值可以为 null。
- @NonNull: 表示变量、参数或返回值不能为 null。
- @NullMarked:应用于包或类级别,它将指定范围内的所有未注解类型默认指定为非空类型,从而减少重复使用@NonNull 注解的需求。
- @NullUnmarked:允许在特定范围内禁用@NullMarked 的效果,便于在大型项目中逐步采用注解。
CRAC、WRAP 和 INSTANTON
CRaC、WRAP 和 InstantOn 是旨在提升 Java 应用启动和性能的技术,它们都源于检查点/恢复机制这一更广泛的概念,尤其受到 CRIU(用户空间检查点/恢复)的影响。
CRaC,即 Checkpoint 时协调恢复,是一个 OpenJDK 项目,通过捕获一个完全预热后的 JVM 快照——在即时编译(JIT)和应用程序初始化之后——并将其保存为检查点,从而提升 Java 启动时间。在底层使用 CRIU 技术,CRaC 会暂停应用程序,通过其 Java API 确保文件和套接字等资源关闭(使用回调如 beforeCheckpoint 和 afterRestore),并将进程状态转储到磁盘——就像视频游戏模拟器中的存档功能。稍后,这个快照可以快速恢复,跳过常规的预热阶段,实现近乎即时的启动并从一开始就提供全性能。Spring 和 Quarkus 等框架已集成 CRaC 支持,利用其显式协调资源的能力,这比 CRIU 更通用、非协调的进程冻结更进一步。
WRAP(Warp Restore Acceleration Platform)和 InstantOn 基于类似的检查点/恢复思想,但针对不同的使用场景,同时共享 CRIU 的基础影响。WRAP 是 Azul 商业产品的一部分,通过优化大规模部署的恢复过程来扩展类似 CRaC 的功能,专注于减少内存占用和加速重复启动——非常适合云原生或容器化环境。而 InstantOn 则针对嵌入式系统和物联网,使用 CRIU 创建一个预初始化的 JVM 镜像,可在毫秒内启动,完全绕过传统的 JVM 启动过程。与 CRaC 的运行时协调不同,InstantOn 强调一次性检查点嵌入到可部署的工件中,而 WRAP 则优化了可扩展性。
这三个工具都源自 CRIU 冻结和恢复 Linux 进程的能力,但在应用范围上有所不同:CRaC 作为开源 JVM 增强,WRAP 作为企业级优化,以及 InstantOn 作为轻量级嵌入式解决方案,它们各自将 CRIU 的原始能力针对 Java 的独特需求进行了定制。
JExtract
jextract 是作为 OpenJDK 项目 Panama 的一部分开发的一个工具,用于通过从 C 头文件自动生成 Java 绑定来简化从 Java 调用本地 C 库。它通过使用 Clang C API 解析头文件,然后生成利用外部函数和内存 API(FFM API,在 JDK 22 中最终确定)与本地代码交互的 Java 类来工作。
这消除了手动创建方法句柄或内存布局的需要,允许开发人员像调用常规 Java 方法一样调用本地函数,同时具有类型安全性和通过竞技场进行资源管理。它特别适用于将遗留 C 库或系统 API 集成到 Java 应用程序中,简化了曾经通过 JNI(Java 本地接口)进行的繁琐过程。
OpenRewrite
OpenRewrite 是一个自动化重构工具,旨在帮助开发者消除其代码库中的技术债务。该项目具备一个引擎,可应用由社区驱动的预构建“配方”来自动化框架迁移、安全漏洞修复和风格一致性更新等任务,将原本可能需要数小时或数天的工作缩短为只需几分钟。这些配方基于源代码的无损语义树(LST)表示进行操作,在保留原始格式的同时,能够实现精确的、类型感知的修改。
最初专注于 Java,OpenRewrite 现在正在扩展以支持其他语言。虽然该项目在 Apache 2.0 许可证下进行维护,但 OpenRewrite 背后的公司 Moderne 正试图将这项技术扩展到企业使用,并围绕它建立合适的商业模式。2025 年 2 月,他们宣布了一轮 3000 万美元的 B 轮融资。
Project Leyden
莱登项目是一个 OpenJDK 倡议,旨在通过转向更静态的、提前编译(AOT)的编译模型来提高 Java 应用程序的启动时间、峰值性能和内存占用。该项目启动是为了解决 Java 缓慢的预热和资源需求这一长期存在的批评,莱登试图通过探索“封闭世界”假设——在构建时整个应用程序是已知的——来进化 JVM,从而允许比传统动态的、“开放世界”方法更激进的优化。
它基于现有的技术,如 GraalVM Native Image 和 JDK 中的 Ahead-of-Time 编译,但重点是将这些理念直接集成到 OpenJDK 中。通过预先计算类加载、链接和 JIT 编译步骤,将它们整合到一个可执行文件或预初始化状态中,Leyden 旨在提供更快的启动速度和减少运行时开销,使 Java 在与 Go 或 Rust 等语言在无服务器和容器化环境中更具竞争力。
该项目分阶段运作,从"冷凝器"等概念开始,将字节码转化为优化形式,可能生成原生二进制文件或缓存运行状态,同时保留 Java 的可移植性和安全性保证。与 CRaC 或 InstantOn 等工具不同,后者会快照正在运行的 JVM,Leyden 强调构建时的转换,避免运行时快照依赖。截至 2025 年初,该项目仍处于实验阶段,没有固定发布日期,但由 OpenJDK 社区内的协作力量指导,以平衡性能提升与 Java 的灵活性。
深渊层
你已抵达一个没有底部的境地,只有永恒的虚空,其中盘踞着最转瞬即逝的项目,一旦你鼓起勇气问出"但我在生产中如何使用这个?",它们便准备将你吞噬。
然后,你将成为深渊的一部分,不再是程序员,而是一个本不该被唤醒的载具。知识已将你吞噬,而你……你将永远无法再编写另一个控制器。
Chicory
菊苣是一个基于 Java 的 WebAssembly 解释器,允许 Wasm 模块在 JVM 中本地运行。与传统的编译器将 Wasm 转换为机器级指令不同,它直接处理字节码,绕过额外的编译阶段,采用了一种简化的方法。
菊苣完全基于 Java 的核心库构建,完全避免了外部依赖。这种精简的设计提高了其在不同系统间的可移植性,并大幅降低了与第三方代码相关的安全漏洞风险,尽管它在速度上有所牺牲,因为解释执行通常不如预编译二进制文件的效率高。
Manifold
在顶层,我们有 Lombok,现在该关注它的更隐藏的伙伴了。
Manifold 是一个 Java 编译器插件,它通过一系列高级功能扩展了语言,如元编程、扩展方法、运算符重载、属性和模板。例如,它允许开发者在 Java 代码中直接以类型安全的方式集成各种数据格式(如 JSON、SQL、XML),从而消除了单独的代码生成步骤的需要。
Manifold 的一个主要优势是通过简化代码和减少样板代码来提高生产力。例如,你可以向现有类(如 String)添加自己的方法,在 Java 代码中使用原生 SQL 并立即获得类型安全,或者编写支持完整 Java 表达式语法的模板。
Manifold 与其他工具(如 Lombok)不同,因为它作为编译器扩展而不是独立语言运行,尽管从技术上讲,它更脆弱,因为它依赖于 javac 的内部机制,这使其与特定的 JDK 版本绑定。
TornadoVM
TornadoVM 诞生于一项研究计划,旨在加速 Java 代码在现代加速器上的执行——这些是专门设计用于加速特定计算的硬件,通常通过大规模并行处理实现,如 GPU 或 FPGA。该项目始于 2018 年左右,作为曼彻斯特大学研究的一部分逐渐成型。
开发者为自己设定的主要挑战是创建一个专门的即时编译器(JIT)和多层运行时逻辑,能够自动检测适合并行执行的部分代码,并将其动态卸载到 GPU(或其他设备)。随着时间的推移,TornadoVM 扩展了额外的后端(OpenCL、CUDA PTX 和 SPIR-V),使其成为一个通用的环境,可在各种类型的硬件上加速 Java 代码。
简单来说:TornadoVM 的目标是减少那些希望使用纯 Java 编写但仍然想利用传统 CPU 之外计算能力的开发者的工作量。
Project Babylon & HAT
巴比伦是一个新的 OpenJDK 项目,通过代码反射增强 Java 的反射功能,能够对方法、lambda 表达式和运行时行为进行深度分析,而不仅仅是简单的类和字段检查。这促进了纯 Java 中的高级元编程,允许动态代码生成和修改。虽然与 TornadoVM 的硬件焦点不同,但巴比伦的反射创新为跨不同平台优化 Java 应用程序提供了潜在协同效应。
其子项目 HAT(异构加速器工具包)旨在通过支持 CUDA、OpenCL 和 Vulkan API 的抽象层来加速 GPU。HAT 允许开发人员在编译时定义“代码模型”,这些模型在运行时被转换为低级的 OpenCL C 或 CUDA PTX。这使并行 Java 应用程序能够高效地利用 GPU,同时保持在 Java 生态系统内开发,类似于 TornadoVM 的目标,但由基于反射的技术驱动。
Babylon 和 HAT 的目标是赋予开发者使用 Code Reflection 的灵活性和 HAT 的硬件集成来编写高性能、GPU 加速的 Java 应用程序的能力。这种组合支持针对科学计算或实时数据处理等任务的优化解决方案,全部在纯 Java 中实现,无需底层专业知识。Babylon 仍在发展中,可以补充像 TornadoVM 这样的项目,增强 Java 的高性能计算能力。