簡體   English   中英

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

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

我在基於JBoss的Web應用程序中使用JAXBContext.newInstance操作。 據我所知,這項行動是非常重量級的。 我只需要Marshaller類的兩個唯一實例。

我最初的建議是有一個靜態初始化程序塊,它只在類加載時初始化這兩個實例:

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(...);
            ...
    }

}

如果這是一個合理的解決方案,那么我想我已經回答了我自己的問題,但我想知道這是否是正確的方法呢?

JAXB實現( MetroEclipseLink MOXyApache JaxMe等)通常在JAXBContext.newInstance調用期間初始化其元數據。 所有OXM工具都需要在某個時刻初始化映射元數據,並嘗試最小化此操作的成本。 由於不可能以零成本完成,因此最好只進行一次。 JAXBContext的實例是線程安全的,所以是的,你只需要創建一次。

從JAXB 2.2規范,第4.2節JAXB上下文:

為避免創建JAXBContext實例所涉及的開銷,建議JAXB應用程序重用JAXBContext實例。 抽象類JAXBContext的實現需要是線程安全的,因此,應用程序中的多個線程可以共享同一個JAXBContext實例。

Marshaller和Unmarshaller的實例不是線程安全的,不能在線程之間共享,它們是輕量級的。

JAXBContext應該始終是靜態的,它是線程安全的。

Marshallers和Unmarshallers很便宜而且不是線程安全的。 您應該創建一次JAXBContext並為每個操作創建marshallers / unmarshallers

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(...);
            ...
    }

}

使用相同的marshaller來編組所有內容(在創建上下文時添加所有類)。

我最近使用JAXBContext.newInstance進行了一些性能測試,結果記錄在這里。

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

當一個線程調用時,使用一個包含~195個類的相當大的模式,完成需要大約400ms。 當同時被20個線程調用時,它會引起cpu爭用,並且需要大約5000ms才能完成。 marshaller和對象序列化的創建只是一個小對象~14ms。

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

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

您應該為每個bean類創建單個JAXBContext對象。 看到這個

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM