【问题标题】:How to preload used class when JVM starts?JVM启动时如何预加载使用的类?
【发布时间】:2021-02-08 11:50:44
【问题描述】:

我正在使用 Java 开发一个需要低延迟处理(不到 1 秒)的消息传递系统。但是,JVM 需要预热时间来处理导致延迟增加的第一个输入数据(大约 2~3 秒)。延迟增加的主要原因是类加载。我知道最简单的解决方案是使用虚拟消息提前调用方法。但是,由于系统要求,我不能使用虚拟消息来预热 JVM。所以想知道在JVM启动时预加载所有使用的类的方法。

我尝试了通过属性强制加载方法

-XX:CompileThreshold=0 -XX:TieredCompilation

但是,它似乎运行得并不好。 JVM 在调用类时仍然会加载它们。

我也读过其他线程,但没有人指定在 JVM 启动时预加载类的方法。

Preloading java classes/libraries at jar startup?

Technique or utility to minimize Java "warm-up" time?

【问题讨论】:

  • 不要混淆“加载”、“初始化”、“编译”和“优化”。即使是提前优化,在不了解实际行为的情况下也可能导致代码无法满足实际需求。因此,当您想避免反优化和重新优化和编译时,您应该考虑强制应用程序以典型方式采用相关路径的虚拟消息。 “因为系统要求”并不是不这样做的令人信服的理由。如果您的系统没有测试功能,则说明您的系统有问题。
  • 感谢 cmets。我想要做的是在执行之前加载类。我提到编译选项的原因是我读了一篇博客 (baeldung.com/java-jvm-warmup),上面说编译选项导致强制类加载。我知道使用虚拟消息是正确的方法,但我想知道是否还有其他选择。
  • 我不太明白那个页面在说什么。
  • 这正在成为一种模式。每次,我在 stackoverflow 问题中看到 baeldung.com 链接,我已经期待一篇草率的文章造成更多的混乱而不是澄清。第 3 点链接到与 JVM 代码缓存无关的 IBM WebSphere servlet 输出缓存。除此之外,它列出了一些毫无价值的陈词滥调。当您添加预热操作但将其排除在测量之外时,测量时间会明显变短,而整体启动时间会变长。但它没有说编译强制加载。这是第一次(“热身”)执行。

标签: java jvm jit hotspot warm-up


【解决方案1】:

我认为您需要使用提前 (AOT) Java 编译器,将类编译为可由 JVM 加载的本机代码。

一个例子是 jaotc 工具,它是在 Java 9 中作为 JEP 295 工作的结果引入的。它需要一个类列表(之前编译为字节码文件)并将它们编译为本机代码库;例如Linux .so 文件。然后你可以在命令行告诉JVM .so文件,它会加载AOT编译的代码并使用它。

AOT 编译的好处是 JVM 启动速度更快。缺点是 AOT 编译器在优化方面不如 JIT 编译器,因此在长时间运行的程序中整体性能会受到影响。

因此,您(明显)需要满足快速启动要求可能会导致您无法满足长期吞吐量要求。

其他参考资料:

【讨论】:

  • 这是满足需求的好方法。谢谢!但是,我还是想知道在执行之前是否有其他的加载类的方法,比如指定一些选项。
  • 没有选项可以做到这一点。此外,问题可能不是加载本身。更可能的是 1) 收集分析信息和 2) 运行 JIT 编译器所花费的时间。此外,由于初始堆扩展,还有其他热身效应。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-15
  • 2018-09-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多