讲JVM的预热,就离不开JVM的类加载, JVM的三个类加载器:Bootstrap、ExtClassLoader、AppClassLoader
JVM预热 : JVM Warm Up
一旦类加载完成,所有重要的类(在进程启动时使用)都会被推送到JVM缓存(本机代码)中,这使得它们在运行时可以更快地访问。其他类是根据每个请求加载的。
对Java Web应用程序的第一个请求通常比进程的生命周期中的平均响应时间慢得多。这个预热期通常可以归因于延迟类加载和及时编译。
记住,对于低延迟应用程序,我们需要预先缓存所有类,以便在运行时访问时立即可用。
这种调优JVM的过程称为预热。
由于JVM的良好体系结构,在应用程序生命周期中,经常使用的方法被加载到本地缓存中。我们可以使用此属性在应用程序启动时强制将关键方法加载到缓存中。在这种程度上,我们需要设置一个名为“TieredCompilation”的VM参数:
-XX:CompileThreshold -XX:TieredCompilation
通常,VM使用解释器收集有关方法的分析信息,这些方法被送入编译器。在分层方案中,除了解释器之外,客户机编译器还用于生成方法的编译版本,这些方法收集有关其自身的分析信息。
由于编译后的代码比解释后的代码快得多,因此在分析阶段,程序的执行性能更好。
public class Dummy {
public void m() {
}
}
public class ManualClassLoader {
protected static void load() {
for (int i = 0; i < 100000; i++) {
Dummy dummy = new Dummy();
dummy.m();
}
}
}
public class MainApplication {
static {
long start = System.nanoTime();
ManualClassLoader.load();
long end = System.nanoTime();
System.out.println("Warm Up time : " + (end - start));
}
public static void main(String[] args) {
long start = System.nanoTime();
ManualClassLoader.load();
long end = System.nanoTime();
System.out.println("Total time taken : " + (end - start));
}
}
运行结果:
Warm Up time : 5213663
Total time taken : 872901
正如预期的那样,预热方法比普通方法显示出更好的性能。
当然,这是一个非常简单的基准,只提供了一些关于这种技术影响的表面层次的洞察。此外,重要的是要了解,对于真实的应用程序,我们需要预热系统中的典型代码路径。
我们还可以使用一些工具来预热JVM。最著名的工具之一是Java Microbenchmark Harness(JMH)。它通常用于micro-benchmarking。一旦它被加载,它就会重复地点击一个代码片段并监视预热迭代周期。
项目中通过Maven依赖引入:
<dependency>
<groupId>org.openjdk.jmhgroupId>
<artifactId>jmh-coreartifactId>
<version>1.19version>
dependency>
<dependency>
<groupId>org.openjdk.jmhgroupId>
<artifactId>jmh-generator-annprocessartifactId>
<version>1.19version>
dependency>
最新版本从添加链接描述这里查看
参考资料:
https://medium.com/teads-engineering/jvm-and-cache-warm-up-strategy-for-high-traffic-services-4b5016f8b565
https://www.baeldung.com/java-jvm-warmup