JAXBContext ускорение инициализации? - PullRequest
27 голосов
/ 27 апреля 2009

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

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

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

Ответы [ 4 ]

36 голосов
/ 23 ноября 2009

Ссылочная реализация 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.c и x.y.z. Впрочем, это, скорее всего, не повлияет на производительность.

6 голосов
/ 28 апреля 2009

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

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

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

3 голосов
/ 07 мая 2009

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

1 голос
/ 23 ноября 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...