有没有什么方法可以加快javax.xml.bind.JAXBContexts的初始化(大于(1000)个类)?在我们的XML繁重的应用程序中,启动时间大约是10分钟,主要包括JAXBContexts的初始化时间。 : - (
我们在JDK 1.5和org.jvnet.jaxb2.maven2.maven-jaxb2-plugin中使用Sun的JAXB实现来从XSD生成代码。
澄清:问题不在于我们有许多具有相同上下文路径的JAXBContext实例,但问题是单个JAXBContext的初始化需要几十秒,因为它必须加载和处理数千个类。 (我们的XSD相当庞大和复杂。)所有JAXBContext实例都有不同的上下文路径 - 我们无法进一步减少数量。
答案 0 :(得分:36)
JAXB参考实现具有一种未记录的系统属性,正是出于这个原因:
-Dcom.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.fastBoot=true
或包重构之前的旧版本:
-Dcom.sun.xml.bind.v2.runtime.JAXBContextImpl.fastBoot=true
这指示JAXB跳过预先缓存执行工作所需的各种反射肌肉的昂贵过程。相反,它将在使用上下文时执行所有反射。这会使运行时间变慢,但初始化速度要快得多,尤其是对于大量的类。
然而,速度问题的一部分是不可避免的,而且事实是JAXB必须加载你的每一个类,并且类加载很慢。如果你在第一个上下文后立即创建第二个上下文,使用相同的配置,这是显而易见的 - 你会看到已经加载了类的速度快得多。
另外,您说您有多个JAXBContext实例,因为您有多个上下文路径。您是否意识到可以将多个上下文路径放入单个上下文中?初始化上下文时,您只需将它们全部作为以分号分隔的字符串传递,例如。
JaxbContext.newInstance("a.b.c:x.y.z");
将加载上下文a.b.c
和x.y.z
。但是,它可能不会对性能产生任何影响。
答案 1 :(得分:6)
通常,您不必创建JAXBContext的许多实例,因为它们在配置后是线程安全的。在大多数情况下,只需一个上下文就可以了。
为什么有很多实例被创建的具体原因?也许假设它们不是线程安全的? (这是可以理解的,因为这没有明确记录 - 但它是一种非常常见的模式,需要在配置期间进行同步,但在使用期间不会,只要配置没有更改)。
除此之外,如果这仍然是一个问题,分析瓶颈&在jaxb.dev.java.net提交问题(指向配置文件中的热点)将有助于改进。 JAXB团队非常好,反应灵敏,如果你能够证明问题所在,他们通常会提出好的解决方案。
答案 2 :(得分:3)
JAXBContext确实是线程安全的,因此建议用单例包装它。我写了一个包含类 - >上下文映射的简单单例,它似乎可以完成这项工作。如果您的应用程序使用多个线程,您可能还想创建一个[un] marshaller对象池,因为这些对象不是线程安全的,您也可能会看到一些初始化惩罚。
答案 3 :(得分:1)
在我们的例子中,更新JAXB库是个好主意。在本质上,即使在开发环境中使用服务器VM而不是客户端VM也是一个好主意,即使它通常会减慢服务器启动速度:因为JAXB初始化需要花费很多时间才能更好地编译服务器VM。