java 如何提高使用 JAXBContext.newInstance 操作的应用程序的性能?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6043956/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 14:06:25  来源:igfitidea点击:

How do I improve performance of application that uses the JAXBContext.newInstance operation?

javaxmljaxb

提问by ryan

I use the JAXBContext.newInstance operation in my JBoss based web application. This operation, as I understand, is very heavyweight. I only require two unique instances of the Marshaller class.

我在基于 JBoss 的 Web 应用程序中使用 JAXBContext.newInstance 操作。这个操作,据我了解,是非常重量级的。我只需要 Marshaller 类的两个唯一实例。

My initial proposal is to have a static initializer block that will initialize these two instances only once upon the class loading:

我最初的建议是有一个静态初始化块,它只会在类加载时初始化这两个实例一次:

public class MyWebApp {
    private static Marshaller requestMarshaller;
    private static Marshaller responseMarshaller;

    static {
        try {
            // one time instance creation
            requestMarshaller = JAXBContext.newInstance(Request.class).createMarshaller();
            responseMarshaller = JAXBContext.newInstance(Response.class).createMarshaller();
        } catch (JAXBException e) {
            e.printStackTrace();
        }
    }

    private void doSomething() {
            requestMarshaller.marshall(...);
            responseMarshaller.marshall(...);
            ...
    }

}

If this is a reasonable solution then I guess I'll have answered my own question, but I would like to know if this is the correct way to do this?

如果这是一个合理的解决方案,那么我想我会回答我自己的问题,但我想知道这是否是正确的方法?

回答by bdoughan

A JAXB implementation (Metro, EclipseLink MOXy, Apache JaxMe, etc) typically initializes its metadata during the JAXBContext.newInstancecall. All OXM tools need to initialize mapping metadata at some point and try to minimize the cost of this operation. Since it is impossible to do it with zero cost, it is best to only do it once. Instances of JAXBContext are thread safe, so yes you only need to create it once.

JAXB 实现(MetroEclipseLink MOXyApache JaxMe等)通常在JAXBContext.newInstance调用期间初始化其元数据。所有的 OXM 工具都需要在某个时候初始化映射元数据,并尝试最小化此操作的成本。既然不可能做到零成本,最好只做一次。JAXBContext 的实例是线程安全的,所以是的,您只需要创建一次。

From the JAXB 2.2 Specification, Section 4.2 JAXB Context:

来自 JAXB 2.2 规范的第 4.2 节 JAXB 上下文:

To avoid the overhead involved in creating a JAXBContext instance, a JAXB application is encouraged to reuse a JAXBContext instance. An implementation of abstract class JAXBContext is required to be thread-safe, thus, multiple threads in an application can share the same JAXBContext instance.

为了避免创建 JAXBContext 实例所涉及的开销,鼓励 JAXB 应用程序重用 JAXBContext 实例。抽象类 JAXBContext 的实现要求是线程安全的,因此应用程序中的多个线程可以共享同一个 JAXBContext 实例。

Instances of Marshaller and Unmarshaller are not thread safe and must not be shared among threads, they are lightweight to create.

Marshaller 和 Unmarshaller 的实例不是线程安全的,不能在线程之间共享,它们是轻量级的。

回答by cocorossello

JAXBContext should always be static, it is thread safe.

JAXBContext 应该总是静态的,它是线程安全的。

Marshallers and Unmarshallers are cheap and not thread safe. You should create once JAXBContext and create marshallers/unmarshallers for every operation

Marshallers 和 Unmarshallers 很便宜,而且不是线程安全的。您应该创建一次 JAXBContext 并为每个操作创建编组器/解组器

public class MyWebApp {
    private static JAXBContext jaxbContext;

    static {
        try {
            // one time instance creation
            jaxbContext = JAXBContext.newInstance(Request.class, Response.class);
        } catch (JAXBException e) {
            throw new IllegalStateException(e);
        }
    }

    private void doSomething() {                
            jaxbContext.createMarshaller().marshall(...);
            ...
    }

}

Use same marshaller to marshall everything (add all classes when you create the context).

使用相同的编组器来编组所有内容(在创建上下文时添加所有类)。

回答by user1738754

I recently did some performance testing with JAXBContext.newInstance and the result is documented here .

我最近使用 JAXBContext.newInstance 进行了一些性能测试,结果记录在此处。

http://app-inf.blogspot.com/2012/10/performance-tuning-logging-right-way.html

http://app-inf.blogspot.com/2012/10/performance-tuning-logging-right-way.html

When called by one thread, using a fairly large schema with ~195 classes generated, it took ~400ms to finish. When called by 20 threads simultaneously, it caused cpu contentions, and took up to ~5000ms to finish. The creation of marshaller and object serialization of a small object only too ~14ms.

当被一个线程调用时,使用一个相当大的模式,生成了大约 195 个类,大约需要 400 毫秒才能完成。当同时被 20 个线程调用时,它会导致 CPU 争用,并需要大约 5000 毫秒才能完成。一个小对象的编组器的创建和对象序列化也只有大约 14 毫秒。

回答by sandeep kale

One can use javax.xml.bind.JAXB. It has direct Marshal and unmarshal methods. So you don't have to worry about instance creation of JAXB.

可以使用 javax.xml.bind.JAXB。它有直接的 Marshal 和 unmarshal 方法。因此您不必担心 JAXB 的实例创建。

e.g. JAXB.unmarshal(inputStream/inputFile, outputClassExpected) or JAXB.marshal(jaxbObject, xmlOutputFile/xmlOutputStream)

例如 JAXB.unmarshal(inputStream/inputFile, outputClassExpected) 或 JAXB.marshal(jaxbObject, xmlOutputFile/xmlOutputStream)

回答by Nitin Vavdiya

You should create single JAXBContextobject per bean class. see this

您应该JAXBContext为每个 bean 类创建一个对象。看到这个