Java 启动时如何在JVM中预加载web应用程序类?

Java 启动时如何在JVM中预加载web应用程序类?,java,performance,web-applications,jvm,classloader,Java,Performance,Web Applications,Jvm,Classloader,在我们的web应用程序中,由于类加载,一些页面的第一次加载需要花费很少但明显的额外时间。是否有人有任何聪明的方法在启动时在JVM中预加载web应用程序类 更新:我们现在要做的是在db表中存储700个完整的类名。我们在启动时阅读该表并执行Class.forName。它工作得很好,但我认为可能有一个更聪明的方法。我们使用探查器确定了启动时引用的700个类。Class.forName是我唯一能想到的。我当然有兴趣听到更聪明的选择 另一个选项是选择一组URL,并在启动时运行脚本以命中这些URL 在部署j

在我们的web应用程序中,由于类加载,一些页面的第一次加载需要花费很少但明显的额外时间。是否有人有任何聪明的方法在启动时在JVM中预加载web应用程序类


更新:我们现在要做的是在db表中存储700个完整的类名。我们在启动时阅读该表并执行Class.forName。它工作得很好,但我认为可能有一个更聪明的方法。我们使用探查器确定了启动时引用的700个类。

Class.forName是我唯一能想到的。我当然有兴趣听到更聪明的选择


另一个选项是选择一组URL,并在启动时运行脚本以命中这些URL

在部署jsp页面之前,您始终可以使用第三方jsp编译器(如Jasper)对其进行预编译。

好吧,这不是很聪明,因为它是规范的一部分,但您可以在Web应用程序启动时启动servlet,方法是在Web.xml中的servlet定义中添加load-on-startup元素:

如果您这样做是为了一组具有代表性的服务,或者仅仅是一个可以预加载所有所需内容的servlet,那么您将实现您的目标


如果这还不够,例如,如果您希望从JAR文件加载类,而不实际以有意义的方式初始化它们,并且如果您知道JAR文件在哪里,或者能够确定JAR文件在哪里,那么您可以使用类似于该线程中的代码或稍后的一些帖子。从类列表中,您可以获得类对象,这将有助于加载类,而无需实际实例化实例。

线程中的Class.forName可能会加快速度。从第一页可能被点击的内容开始

线程化应该会使启动更快,它会更早地返回,因为您首先开始加载更可能的类,所以希望在页面被点击时加载它们。对于其他相同的交易,希望在页面被点击之前加载

您还可以更进一步,为每一组类启动一个线程,这些类在给定页面上需要的是一个组。这可能会加快速度,因为您可以并行读取磁盘,但也可能会减慢速度


这并不意味着在第一次加载页面时事情不会变慢,但值得研究。

可能是您可以尝试将700个类转换为jar文件,并应用一些预加载方法,可能通过将jar放在启动类路径中,我不确定它是否有效。但只是给出一个提示。

您可以尝试在单个虚拟类中编写静态初始值设定项代码,然后在启动时加载该类。它的静态初始值设定项将创建一些导致加载其他类的关键对象,您可以递归地这样做以提高代码模块性。我敢打赌,这是短得多,更简单,你没有DB的问题,担心


一个更好的方法可能是编写一个servlet,在启动时点击一些加载缓慢的页面,并丢弃结果。这将强制类加载。每次多次加载这些页面都会增加所完成的即时编译的数量,这既加快了代码的速度,也降低了JIT编译的成本。还有其他优点:这是一个开机自检,它会导致一次性启动任务的完成,并且它还可以在某种程度上启动各种缓存。

实际的JSP编译不是问题。它正在加载各种已编译的Java库和已编译的JSP文件。对不起。我误解了你的要求。我希望你能找到解决问题的办法。我们会这样做的。这当然只涉及servlet,而不是相关的库。servlet在初始化时不能引用相关的库吗?它们可以。当然,您需要确定正在加载的所有类,然后在servlet中引用它们。我们正在寻找一种更简洁的方法,Java中的类只有在被引用时才会被加载。因此,我知道预加载类的唯一方法是引用它。也许你可以有一个配置文件,列出你想要引用的类,所以它是可配置的。仅仅引用类对象就足够了,我们使用了相当多的库,每个库都有很多类。让JVM只加载给定jar中的所有类的简单方法是什么?或者加载给定包中的所有类?我们可以在一个配置文件中列出每一个类,但那会很麻烦。效果很好。我只是觉得有比我们如何实施更好的方法。这是否回答了你的问题?
<servlet>
  <description>....</description>
  <display-name>....</display-name>
  <servlet-name>....</servlet-name>
  <servlet-class>....t</servlet-class>
  <load-on-startup>1</load-on-startup>
</servlet>