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

Почему Java-отладка "Горячая замена" ограничивается изменениями внутри метода?

Я прочитал учебник для быстрого развертывания, и он работает. Но у меня есть вопросы об ограничениях (пункт 3) i.e

Горячее развертывание поддерживает только изменения кода в реализации метода. Если вы добавляете новый класс или новый метод, перезагрузка по-прежнему требуется.

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

Мое понимание того, как это работает: - Когда я делаю изменения в существующем методе или ввел новый метод, Eclipse поместит файл в нужное место под веб-сервером. Если класс уже загружен загрузчиком классов в пространстве perm gen, он выгрузит его из пространства перменства и загрузит новый внутри внутри без перезапуска сервера, чтобы отобразить новые изменения (байт-код). Это верно?

Если да, то почему горячее развертывание не работает для новых методов и новых файлов классов?

4b9b3361

Ответ 1

Прогнозы довольно сложны и действительно полностью известны людям с глубоким знанием JVM и тем, как он управляет памятью. На этой странице есть достойное объяснение (хотя это действительно реклама для продукта JRebel) - перейдите к разделу под названием Почему HotSwap ограничен телами методов?.

Суть: есть два основных фактора, которые препятствуют обработке HotSwap структурных изменений в классах: JIT и распределение памяти.

Компилятор JIT (Just In Time) в JVM оптимизирует байт-код после того, как классы были загружены и выполняются несколько раз, в основном вставляя много вызовов для повышения производительности. Реализация этой функции безопасно и эффективно в среде, где могут меняться подписи и структура классов, может стать серьезной проблемой.

Другие проблемы окружают то, что произойдет в отношении управления памятью, если структурам классов разрешено изменять. JVM пришлось бы модифицировать существующие экземпляры классов, что означало бы переместить их в другие части хранилища кучи. Не говоря уже о необходимости переместить объекты класса сами. Управление памятью JVM уже невероятно сложно и сильно оптимизировано; такие изменения только увеличили бы сложность и потенциально снизили производительность JIT-компилятора (и, вероятно, приведут к дополнительным ошибкам).

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

Ответ 2

В качестве побочного примечания сама спецификация не ограничена.

Просто случается, что некоторые из доступных реализаций, включая вездесущую Справочную реализацию, ограничены.

После подключения к удаленной виртуальной машине вы можете проверить, разрешено ли добавлять методы или переопределить классы.

Ответ 3

Вы можете, если запустите java на smalltalk vm. Smalltalk делает это в основном навсегда, и это одна из причин, почему Smalltalkers имеют тенденцию делать разработку с отладчиками как превосходную форму разработки, основанной на тестах. Smalltalk vms выполняет необходимую очистку структур данных памяти. В Eliot Miranda Spur (для Squeak, Pharo и Cuis) и Gemstone это делается лениво, но в противном случае вам придется ждать, пока все объекты будут перенесены. Эталонная реализация java vm, вероятно, имеет больше оптимизаций, чем любой smalltalk vm, вы можете запустить java на a.t.m.

Ответ 4

Ответ, предоставленный E-Riz, уже имеет хорошее объяснение причин, по которым стандартная технология Java HotSwap поддерживает только модификации существующих методов, а не добавление новых классов или методов в классы.

Однако, как было описано в связанном обсуждении fooobar.com/info/279064/..., уровень горячей замены, который вы достигаете, зависит от используемой цепочки инструментов. Итак, если вы добавите плагин JRebel, вы сможете выполнять "горячую" замену, даже если новые методы и классы были добавлены.

Существует еще один проект: Агент горячей замены - это, как правило, агент Java, который можно использовать для запуска вашего контейнера Java, и вы можете активируйте его, используя пару параметров командной строки (как указано в quickstart).