#java #sqlite #jvm #classloader
#java #sqlite #jvm #classloader
Вопрос:
Почему виртуальная машина Java не загружает классы из базы данных (аналогично GAC в .NET)? Насколько я понимаю, в настоящее время он должен читать и сканировать манифесты каждого JAR в пути к классу, чтобы найти файлы классов. Разве использование базы данных (например, SQLite) не увеличило бы время запуска?
Комментарии:
1. Конечно, это было бы. Теперь попробуйте заменить JAR более новой версией. Если вам нужен загрузчик классов SQLite, вы можете легко написать его.
Ответ №1:
Этого не происходит, потому что никто не добавил это в стандартные библиотеки. Также для целей начальной загрузки (например, загрузки драйвера JDBC для доступа к БД) существующие механизмы все равно должны присутствовать.
Однако создать загрузчик классов, который взаимодействует с базой данных для извлечения битов класса, не так уж сложно.
Ответ №2:
Ваша фундаментальная точка зрения верна: при загрузке классов Java существуют возможности оптимизации, и очевидно, что при поиске классов выполняется много дублированной работы, особенно тех, которые часто используются. Производители JVM на самом деле уже проделали довольно большую работу в этой области. Смотрите Описание общих данных Oracle для примера.
Я предполагаю, что накладные расходы и сложности использования базы данных чрезмерны для того, что фактически является простой проблемой кэширования и индексирования.
Ответ №3:
Ведется очень активная работа по увеличению времени запуска (это одна из целей Project Jigsaw, который является частью JDK 8).
Но оптимизация не так проста, как просто «сбросить файлы классов в БД». Здесь есть несколько проблем, некоторые из них конкурируют.
И у GAC есть свои собственные проблемы, ни одну из которых, я думаю, мы не хотели бы повторять…
Ответ №4:
В зависимости от того, как вы определяете «базу данных», как IBM (общие классы), так и Oracle (общие данные) уже имеют технологии для ускорения запуска и уменьшения занимаемой памяти.
Время загрузки классов на самом деле очень мало (для каждого класса), поэтому добавление чего-то вроде базы данных в way не приведет к реальному изменению производительности в лучшую сторону, особенно если вам нужно передавать байты по проводам (а не просто читать запись в jar локальной файловой системы). Все современные JVM сильно оптимизированы по пути загрузки классов, и добавление SQL, безусловно, не улучшит производительность. (гибкость распределенных репозиториев и т.д. — это другой вопрос, и я вижу в этом преимущества.)
Комментарии:
1. Насколько я понимаю, основная проблема заключается в достаточно быстром удалении байтов класса с диска?
2. Правильно — все дело в правильном поиске и загрузке байтов. Задержка на диске и (особенно) в сети будет полностью доминировать во времени загрузки класса.
Ответ №5:
Вы могли бы использовать сервер nexus в качестве хранилища maven для библиотек и загружать их в контейнер OSGi. Это позволяет создавать / развертывать / загружать / выгружать целые библиотеки, не касаясь непосредственно jar или классов. Однако для повышения производительности она размещает локальные копии библиотек на диске и не позволяет вам управлять отдельными классами.
Мне было бы трудно поверить, что загрузка классов через сокет-соединение происходит быстрее, чем загрузка сжатых файлов непосредственно с диска. (как это делает maven / OSGi), особенно когда файл находится в кэше. Большая часть времени, затрачиваемого на загрузку классов, приходится на код, выполняемый в статических блоках, а затем на компиляцию кода, ни с одним из которых база данных вам не помогла бы.
Мне было бы интересно увидеть сравнение производительности. Как репозитории классов базы данных обрабатывают версии? Насколько легко / надежно откатить версию библиотеки, например, или группу классов с взаимозависимостями?
Ответ №6:
Вы можете создать индексный jar, который сообщит среде выполнения, какой класс находится в каком jar. Для этого вы берете основную jar-папку вашего приложения и убедитесь, что атрибут Class-Path правильно установлен в манифесте. Затем вы запускаете «jar -i MyMainJar.jar «чтобы создать индекс.
Если у вас нет основного jar-файла, вы можете создать тот, который просто содержит манифест с установленным атрибутом Class-Path и проиндексировать его. Если вы сначала загрузите этот jar, загрузчик классов будет использовать индекс и быстрее находить классы.