Почему Java-отладка "Горячая замена" ограничивается изменениями внутри метода?
Я прочитал учебник для быстрого развертывания, и он работает.
Но у меня есть вопросы об ограничениях (пункт 3) i.e
Горячее развертывание поддерживает только изменения кода в реализации метода. Если вы добавляете новый класс или новый метод, перезагрузка по-прежнему требуется.
В принципе, нам не нужен перезапуск сервера, если я вношу изменения в существующий метод, но требуемый в случае добавления метода или класса.
Мое понимание того, как это работает: - Когда я делаю изменения в существующем методе или ввел новый метод, Eclipse поместит файл в нужное место
под веб-сервером. Если класс уже загружен загрузчиком классов в пространстве perm gen, он выгрузит его из пространства перменства и загрузит новый внутри внутри без перезапуска сервера, чтобы отобразить новые изменения (байт-код). Это верно?
Если да, то почему горячее развертывание не работает для новых методов и новых файлов классов?
Ответы
Ответ 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).