2009-04-27 34 views
24

有没有什么办法可以加快javax.xml.bind.JAXBContexts的初始化过程(> 1000个)?在我们的XML重型应用程序中,启动时间大约为10分钟,主要由JAXBContexts的初始化时间组成。 :-(JAXBContext初始化加速?

我们使用Sun的JAXB实现在JDK 1.5和org.jvnet.jaxb2.maven2.maven-JAXB2-插件从XSD文件代码生成

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

回答

32

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。不过,这可能对性能没有任何影响。

6

通常,您不应该创建JAXBContext的多个实例,因为它们在线程安全后已配置。在大多数情况下,只有一个上下文是好的。

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

除此之外,如果这仍然是一个问题,那么在jaxb.dev.java.net上提出问题的瓶颈&(从配置文件指向热点)将有助于改进问题。 JAXB团队非常好,反应迅速,如果您能够证明问题出在哪里,他们通常会提出很好的解决方案。

+0

请参阅问题中的说明:每个实例具有不同的上下文路径,因此我们不能减少实例的数量。问题是每个单个实例的初始化需要几十秒。 – 2009-05-14 12:08:13

+0

好的。仍然很好奇是否可以创建一个静态引用相关类的虚拟“根类”,以允许构建一个超级上下文。但可能有其他原因不这样做。 我会建议如果你有时间真的会做简单的分析,并看看时间花在哪里。只要上下文中的任何一个创建缓慢,使用常规JVM和-Xhprof运行,就会在堆栈跟踪中看到一些元凶。 这可能暗示一种解决方法,或者指出JAXB团队改进(s)。 – StaxMan 2009-05-14 20:51:18

+0

@hstoerr因为初始化过程需要大约10秒钟,所以在应用程序启动时并行执行初始化过程是不是最实际? – Nielsvh 2015-11-24 00:17:43

3

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

1

在我们的例子中,更新JAXB库是个好主意。从本质上讲,甚至在开发环境中使用服务器虚拟机而不是客户机虚拟机在这里也是一个好主意,尽管它通常会降低服务器的启动速度:因为JAXB初始化需要很多时间,所以更好地编译服务器虚拟机会有所帮助。