之前跟朋友聊天,提到Java代码运行起来会越来越快、Java代码需要预热。 越来越快,看起来是很厉害的样子,但是这句话的另外一个表述方式是:刚刚启动的时候是很慢的。也就是有一个冷启动过程。 冷启动就是指Java应用并不是即起即用的,而需要经过虚拟机初始化后才能达到可用状态,再经过程序预热才能达到最佳性能。 然后Java语言自从诞生以来就被打上了慢的标签,经常听到的一个自嘲的言论是:你都用Java了,还在乎这点性能? 是的,早早年间Java确实慢。然而,经过近28年的发展,Java程序的峰值性能在实时编译(JIT)技术的支持下已经能够超越CC程序。 但是实时编译仍然无法解决冷启动速度慢的问题。 这玩意就是一个命门了,抓着这一个点就能做出很多文章出来。 在我们传统的单机应用或者通过服务器部署微服务的场景中,这个问题并不明显。 一个原因是应用执行时间足够长,冷启动的问题就被淡化了。第二个原因是我们可以提前将服务预热准备好,以最好的状态迎接用户的服务请求,比如很多框架里面就帮我们做了服务预热的事情。 但是在当下盛行的云原生场景下,当用户的请求源源不断的过来,服务扛不住需要请求支援的时候,我们需要快速的拉起新服务来给到有力的资源。 而拉起新服务的这个过程,就涉及到服务的启动,在争分夺秒的情况下,服务的启动时间就显得至关重要。 所以这个冷启动问题使得Java在云原生的场景下,无法与Node。js、Go等具有快速启动优势的语言竞争。 那么Java怎么办呢,怎么去抢占市场呢,难道要依靠强大的生态吃老本、躺平吗? 肯定不会的。 Java肯定也会在危机中寻求出路,这个出路这就是Java的静态编译技术。 这玩意我之前也提到过:Java静态编译是指将Java程序的字节码在单独的离线阶段编译为汇编代码,其输入为Java的字节码,输出为操作系统本地原生程序。 静态编译技术的出现,将Java程序提前编译为二进制机器码,实现以NativeCode的速度启动Java程序,带来最多两个数量级的启动性能提升。 而该技术代表性的作品就是GraalVM。 与传统Java运行模型相比,GraalVM的静态编译运行模型有两大特点: 一是静态编译后的可执行程序已经是本地程序,而且自包含了轻量级运行时支持,因此不再额外需要Java虚拟机。 没有了JVM,自然也就消除了冷启动问题,使得应用程序达到即起即用的状态。另外,因为JVM的运行也需要消耗一部分内存,去掉JVM后应用程序的内存占用也大幅降低。 二是静态编译后的程序也经过了众多的编译优化,运行时不再需要经过解释执行和JIT编译,既避免了解释执行的低效,也避免了JIT编译的CPU开销,还解决了传统Java执行模型中无法充分预热,始终存在解释执行的问题,因此可以保证应用程序始终以稳定的性能执行,不会出现性能波动。