云时代 JVM 的挑战
首先让我们一起回顾下 Java 那些耳熟能详的特点:everything is object、平台无关性、垃圾回收机制、完善的生态体系。这些曾经让 Java 引以为傲的优势,当云原生时代来临的时候,正在成为牵绊它前行的阻力,云原生时代 Java 的各种缺陷逐渐凸显。
启动时间
首当其冲的就是启动时间,我们都知道 JVM 是个慢热型选手。它在启动时需要加载很多类文件,而如果你的应用需要在启动时候建立各种长链接,那启动时间基本上要以分钟来计算了。
启动性能
其次是启动性能,由于 JVM 需要在系统运行一段时间后才能逐步由解释执行转化为解释执行 + 编译执行,这也意味着 JVM 的系统需要经过一段时间的预热才能达到性能巅峰。这就像冬天的燃油车一样,必须先把发动机充分预热,才能真正上路。
内存占用
相较于在运行态只包含机器码和垃圾回收器的 Go 语言,JVM 的运行态即使只进行简单的加减乘除运算,也需要包含一个完整的解释器、一个即时编译器、一个垃圾回收器,在这个以快著称的云时代,显得有点太重了。
面向对象
曾经 Java 语言就是面向对象的代名词,Java 的那句 Slogan:everything is object,即使没有使用过 Java 语言的人也都听说过。但是你是否思考过,面向对象是否是唯一的选择?everything is object 的成本是什么?
一个 32 位 Integer 对象在内存中的空间占用如下:
对象头部:Header,通常占据 8 个字节。用来存储对象的元数据信息,比如对象的类型指针、锁状态等。
实际存储的整数值:占据 4 个字节,用来存储 32 位整数的值。
因此,一个 32 位的 Integer 对象在运行时会占用 12 字节的内存空间。在实际情况中,JVM 为了对齐内存访问会把结构体的大小向上取整到 8 的倍数,所以通常会占用 16 字节的内存空间。这还不包括内存分配、垃圾回收、并发调用等耗费的其他资源成本。
在这个确定的云时代,我们似乎看到一个不确定的 JVM 的未来。但是作为一个发展了 28 年有着庞大生态支撑的王者,JVM 显然不会坐以待毙,下面我们就来看看 JVM 的应对之道。
拥抱容器化
New Relic 的数据显示,目前已经有 70% 的 Java 应用是运行在容器中的。为了更好地支持容器化,JVM 逐步放弃了自己原本的平台无关的解决方案,转而拥抱容器化。
容器亲和性
在 JDK 8u131 版本之前,JVM 不具备容器识别能力。这对于已经上云,但还在使用 JDK 8 的 Java 应用来说,存在致命的风险。因为 JVM 会基于宿主机的物理内存来设置堆内存的最大值,而不是基于容器的内存限制,从而导致 JVM 试图使用超出容器限制内存的情况出现,进而被操作系统杀掉,CPU 的使用也存在同样的问题。
在 JDK 11、JDK 17 中,JVM 增加了对容器环境的识别能力。JVM 会读取来自操作系统(Docker)和容器管理系统(Kubernetes)提供的信息,来了解它所在的容器的资源限制。JVM 会把这些信息用于堆内存、JIT 编译器的管理中,并且这些新增的功能是默认开启的,无需任何特殊的配置。
AOT 原生镜像编译
从 JDK 9 开始,JVM 支持 AOT(Ahead-Of-Time)编译技术,并在 JDK 11、17 版本中持续增强。AOT 指的是在 JVM 运行之前把代码编译成本地机器码的技术。通过提前将 Java 应用程序编译为即时启动的本地二进制文件,JVM 在无需预热的情况下就可以提供峰值性能。
同时,即时编译会产生大量的中间编译代码和相关的数据结构,导致程序占用更多的内存,而 AOT 编译可以在编译时根据具体平台进行优化,减少了这些额外的开销,节省了内存空间。
函数式支持增强
JVM 持续加强对函数式的支持,参照 Go 语言,通过逃逸分析、栈上分配等操作持续提升栈的利用效率。基于函数式编程风格更加强调不可变性和无副作用的特性,产生的垃圾更少。此外,JVM 还引入了 Epsilon 垃圾收集器,这是一个不执行任何垃圾收集的收集器。当应用程序不需要自动内存管理或者为了测试和性能调整而需要关闭垃圾收集时使用。
JDK 11 对 Lambda 表达式进行了改进,Lambda 参数可利用 var 关键字声明类型,使 Lambda 表达式的代码更加简洁。这些改进和新增特性都彰显出 JVM 在加强函数式编程方面做出的努力。
GraalVM
GraalVM 是 Oracle Labs 于 2018 年 4 月首次公开发布的高性能 JDK 发行版,它的目标是提升在 JVM 上运行的程序的性能,包括 Java、Scala、Groovy、Kotlin 等多种语言。GraalVM 的主要亮点在于其全新的即时(Just-In-Time)编译器,该编译器采用最新的编译器技术和研究成果,对 Java 的程序性能进行了大幅提升。
此文章为8月Day24学习笔记,内容来源于极客时间《云时代的JVM原理与实战 》,强烈推荐该课程
网友评论