28

有什么方法可以加快 javax.xml.bind.JAXBContexts 的初始化与大量(> 1000)类?在我们的 XML 繁重的应用程序中,启动时间大约为 10 分钟,主要包括 JAXBContexts 的初始化时间。:-(

我们在 JDK 1.5 中使用 Sun 的 JAXB 实现,并使用 org.jvnet.jaxb2.maven2.maven-jaxb2-plugin 从 XSD 生成代码。

澄清:问题不在于我们有许多具有相同上下文路径的 JAXBContext 实例,而在于一个 JAXBContext 的初始化需要数十秒,因为它必须加载和处理数千个类。(我们的 XSD 相当大且复杂。)所有 JAXBContext 实例都有不同的上下文路径 - 我们无法进一步减少数量。

4

4 回答 4

42

由于这个原因,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.cx.y.z. 不过,它可能不会对性能产生任何影响。

于 2009-11-23T09:55:12.520 回答
6

通常,您不必创建许多 JAXBContext 实例,因为它们在配置后是线程安全的。在大多数情况下,只需一个上下文就可以了。

那么创建许多实例是否有特定原因?也许有人假设它们不是线程安全的?(这是可以理解的,因为没有明确记录——但这是一种非常常见的模式,需要在配置期间同步,但在使用期间不需要同步,只要不更改配置)。

除此之外,如果这仍然是一个问题,分析瓶颈并在 jaxb.dev.java.net 上提交问题(从配置文件中指出热点)将有助于改善情况。JAXB 团队非常好,反应迅速,如果你能指出问题出在哪里,他们通常会提出很好的解决方案。

于 2009-04-28T18:13:47.310 回答
3

JAXBContext 确实是线程安全的,因此建议使用单例包装它。我写了一个简单的单例,其中包含一个似乎可以完成这项工作的类->上下文映射。如果您的应用程序使用许多线程,您可能还想创建一个 [un]marshaller 对象池,因为这些对象不是线程安全的,并且您也可能会看到一些初始化惩罚。

于 2009-05-07T14:58:57.250 回答
1

在我们的例子中,更新 JAXB 库是一个好主意。顺便说一句,即使在开发环境中使用服务器 VM 代替客户端 VM 也是一个好主意,尽管这通常会减慢服务器启动速度:由于 JAXB 初始化需要很长时间,因此更好地编译服务器 VM 会有所帮助。

于 2009-11-23T09:48:21.990 回答