如何改进使用JAXBContext的应用程序的性能。newInstance操作吗?

时间:2021-10-31 06:35:45

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.

我使用JAXBContext。基于JBoss的web应用程序中的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?

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

5 个解决方案

#1


25  

A JAXB implementation (Metro, EclipseLink MOXy, Apache JaxMe, etc) typically initializes its metadata during the JAXBContext.newInstance call. 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实现(Metro、EclipseLink MOXy、Apache 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.

编组器和反编组器的实例不是线程安全的,并且不能在线程之间共享,它们是创建的轻量级实例。

#2


7  

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

编组器和分组器都很便宜,而且不安全。您应该创建一次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).

使用相同的marshaller对所有内容进行马歇尔处理(在创建上下文时添加所有类)。

#3


4  

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个类的相当大的模式,需要~400ms才能完成。当同时被20个线程调用时,它会引起cpu的竞争,并且需要大约5000ms来完成。一个小对象的编组器创建和对象序列化的过程也只有14ms。

#4


-1  

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之一。它有直接编组和非编组方法。所以您不必担心JAXB的实例创建。

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

例如JAXB。unmarshal(inputStream / inputFile outputClassExpected)或JAXB。元帅(jaxbObject xmlOutputFile / xmlOutputStream)

#5


-1  

You should create single JAXBContext object per bean class. see this

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

#1


25  

A JAXB implementation (Metro, EclipseLink MOXy, Apache JaxMe, etc) typically initializes its metadata during the JAXBContext.newInstance call. 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实现(Metro、EclipseLink MOXy、Apache 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.

编组器和反编组器的实例不是线程安全的,并且不能在线程之间共享,它们是创建的轻量级实例。

#2


7  

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

编组器和分组器都很便宜,而且不安全。您应该创建一次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).

使用相同的marshaller对所有内容进行马歇尔处理(在创建上下文时添加所有类)。

#3


4  

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个类的相当大的模式,需要~400ms才能完成。当同时被20个线程调用时,它会引起cpu的竞争,并且需要大约5000ms来完成。一个小对象的编组器创建和对象序列化的过程也只有14ms。

#4


-1  

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之一。它有直接编组和非编组方法。所以您不必担心JAXB的实例创建。

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

例如JAXB。unmarshal(inputStream / inputFile outputClassExpected)或JAXB。元帅(jaxbObject xmlOutputFile / xmlOutputStream)

#5


-1  

You should create single JAXBContext object per bean class. see this

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