Подтвердить что ты не робот

Ускорение инициализации JAXBContext?

Есть ли способ ускорить инициализацию javax.xml.bind.JAXBContexts с большим ( > 1000) числом классов? В нашем тяжелом приложении XML время запуска составляет около 10 минут и состоит в основном из времени инициализации JAXBContexts.: - (

Мы используем реализацию Sun JAXB в JDK 1.5 и org.jvnet.jaxb2.maven2.maven-jaxb2-plugin для генерации кода из XSD.

Уточнение: проблема заключается не в том, что у нас есть много экземпляров JAXBContext с одинаковыми контекстными путями, но проблема в том, что инициализация одного JAXBContext занимает десятки секунд, так как ему приходится загружать и обрабатывать тысячи классов. (Наши XSD довольно большие и сложные.) Все экземпляры JAXBContext имеют разные контекстные пути - мы не можем уменьшить число дальше.

4b9b3361

Ответ 1

Ссылочная реализация 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");

загрузит контексты abc и xyz. Впрочем, это вряд ли повлияет на производительность.

Ответ 2

В общем, вам не нужно создавать много экземпляров JAXBContext, поскольку они являются потокобезопасными после их настройки. В большинстве случаев только один контекст в порядке.

Итак, есть ли конкретная причина, почему многие экземпляры создаются? Возможно, было предположение, что они не являются потокобезопасными? (что понятно, учитывая, что это явно не документировано, но это очень распространенный шаблон, требуется синхронизация во время настройки, но не во время использования, пока конфигурация не изменяется).

Кроме этого, если это все еще проблема, узкие места профилирования и подача проблемы на jaxb.dev.java.net(указание горячих точек из профиля) помогут улучшить ситуацию. Команда JAXB очень хороша, отзывчива, и если вы можете показать, где проблемы, они обычно приходят с хорошими решениями.

Ответ 3

JAXBContext действительно потокобезопасен, поэтому рекомендуется обертывать его одним синглтоном. Я написал простой синглтон, содержащий кластер- > контекстную карту, которая, похоже, выполняет эту работу. Вы также можете создать пул объектов [un] marshaller, если вы используете много потоков, поскольку эти объекты не являются потокобезопасными, и вы можете также увидеть некоторые меры по их инициализации.

Ответ 4

В нашем случае обновление библиотек JAXB было хорошей идеей. Кстати, использование серверной VM вместо клиентской VM даже в среде разработки было хорошей идеей здесь, хотя обычно это замедляет запуск сервера: поскольку инициализация JAXB занимает так много времени, лучшая компиляция серверной VM помогает.