Как выгрузить класс из загрузчика классов, чтобы я мог использовать недавно измененный класс на лету без перезапуска приложения (горячее развертывание)? Возможно ли это?
Как выгрузить уже загруженный класс в Java?
Ответы (4)
Java Rebel перезагружает измененные классы на лету. Подробную информацию см. На веб-сайте jrebel. Я не знаю, что рекомендовал бы это для производственной среды из-за проблем с производительностью. JRebel иногда на мгновение сбивает с толку, когда вы перекомпилируете для сервера.
Вы не можете выгрузить класс, который действительно используется. Но вы можете взглянуть на такие платформы, как OSGi, если вы хотите перезагрузить или повторно развернуть приложение во время выполнения.
Вы не можете явно выгрузить класс.
В принципе, вы можете явно перезагрузить класс через Classloader.loadClass (). С этого момента все новые экземпляры этого класса будут использовать новое определение.
В любом случае, я буду действовать с особой осторожностью ...
Вам нужно будет создать собственный ClassLoader
:, который возвращает все Object
, завернутые внутри прокси. ClassLoader
должен иметь список всех прокси, на которые есть ссылки (сохраните этот список WeakReference
d). Если вы решите «выгрузить» и, таким образом, «перезагрузить» какой-либо класс, вы ждете, пока класс загрузится, находите все прокси в своем списке и заменяете фактический объект.
Есть несколько проблем: вам нужно Reflection, чтобы получить все частные переменные и сбросить внутреннее состояние (см. setAccesible
на Field
). Также могут возникнуть проблемы с многопоточностью, поэтому прокси-сервер должен быть синхронизирован: что снижает его производительность.
Вам лучше поискать решение для зависимостей Guice от Google, которое позволяет отключать и перезагружать модули во время выполнения. Это могло бы быть решением, но слишком раздутым для небольшого приложения. Тем не менее: я не уверен, выгружает ли GC также неиспользуемые классы.