Ускорение инициализации JAXBContext?
Есть ли способ ускорить инициализацию javax.XML.связывать.JAXBContexts с большим (>1000) числом классов? В нашем XML-тяжелом приложении время запуска составляет около 10 минут и состоит в основном из времени инициализации JAXBContexts. :- (
Мы используем реализацию Sun JAXB в JDK 1.5 и org.спнет.jaxb2.maven2.maven-jaxb2-плагин для генерации кода с XSDs.
Уточнение: проблема не в том, что у нас есть много примеров JAXBContext с теми же contextpaths, но проблема в том, что инициализация одного единственного JAXBContext занимает десятки секунд, так как он должен загрузить и обработать тысячи классов. (Наши xsd довольно большие и сложные.) Все экземпляры JAXBContext имеют различные contextpaths - мы не можем уменьшить их число дальше.
4 ответов:
Ссылочная реализация JAXB обладает своего рода недокументированным системным свойством именно по этой причине:
-Dcom.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.fastBoot=trueИли для старых версий до рефакторинга пакета:
Это дает указание JAXB пропустить дорогостоящий процесс предварительного кэширования различных мышц отражения, необходимых для выполнения этой работы. Вместо этого он будет делать все рефлексии, когда контекст будет использоваться. Это приводит к более медленному времени выполнения, но значительно быстрее инициализации, особенно для большого количества занятия. Однако одна часть проблемы скорости неизбежна, и это тот факт, что JAXB должен загрузить каждый из ваших классов, а загрузка классов происходит медленно. Это очевидно, если вы создадите 2-й контекст сразу после первого, с той же конфигурацией - вы увидите, что это намного, намного быстрее, уже загрузив классы.-Dcom.sun.xml.bind.v2.runtime.JAXBContextImpl.fastBoot=trueКроме того, вы говорите, что у вас есть несколько экземпляров JAXBCOntext, потому что у вас есть несколько contextpaths. Вы поняли, что можете поставить несколько путей контекста в один контекст? Вам просто нужно передать их все в виде строки, разделенной точкой с запятой, когда вы инициализируете контекст, например
JaxbContext.newInstance("a.b.c:x.y.z");Загрузит контексты
a.b.cиx.y.z. Хотя, скорее всего, это не повлияет на производительность.
В общем случае вам не нужно создавать много экземпляров JAXBContext, так как они потокобезопасны после настройки. В большинстве случаев достаточно одного контекста.
Так есть ли конкретная причина, по которой создается много экземпляров? Возможно, было предположение, что они не являются потокобезопасными? (что понятно, учитывая, что это не четко задокументировано - но это очень распространенный шаблон, нуждающийся в синхронизации во время конфигурации, но не во время использования, пока config не является измененный).
Кроме этого, если это все еще проблема, профилирование узких мест и подача вопроса на jaxb.dev.java.net (указывая горячие точки из профиля) поможет улучшить ситуацию. Команда JAXB очень хорошая, отзывчивая, и если вы можете показать, где проблемы, они обычно приходят с хорошими решениями.
JAXBContext действительно потокобезопасен, поэтому рекомендуется обернуть его синглетом. Я написал простой синглтон, содержащий контекстную карту класса ->, которая, кажется, делает эту работу. Вы также можете создать пул объектов маршаллера [un], если ваше приложение использует много потоков, так как эти объекты не являются потокобезопасными, и вы можете увидеть некоторые штрафы инициализации с ними.
В нашем случае обновление библиотек JAXB было хорошей идеей. Кстати, использование серверной виртуальной машины вместо клиентской виртуальной машины даже в среде разработки было хорошей идеей здесь, хотя обычно это замедляет запуск сервера: поскольку инициализация JAXB занимает так много времени, лучшая компиляция серверной виртуальной машины помогает.
Comments