Возможно ли иметь исправление во время выполнения с исполняемыми кучами памяти и распределенной системой?

Я просмотрел несколько руководств по JIT и выделению кучи исполняемой памяти во время выполнения. Это в основном концептуальный вопрос, поэтому, пожалуйста, поправьте меня, если я что-то не так.

Если я правильно понимаю, JIT использует интерпретатор/компилятор времени выполнения, который выводит собственный или исполняемый код и, если собственный двоичный код, помещает его в кучу исполняемого кода в памяти, которая зависит от ОС (например, VirtualAlloc() для Windows , mmap() для Linux).

Кроме того, некоторые языки, такие как Erlang, могут иметь распределенную систему, так что каждая часть отделена друг от друга, а это означает, что в случае сбоя одной из них другие могут учитывать такой случай модульным образом, а это означает, что модули также могут включаться и отключаться. по желанию, если им правильно управлять, не нарушая общего исполнения.

С компилятором времени выполнения или каким-либо механизмом доставки кода, не будет ли возможно произвольно загружать код во время выполнения, чтобы заменить модули кода, которые можно обновить?

Пример

Скажем, у меня есть функция sort(T, T), которая работает с T или T. Теперь предположим, что у меня есть функция merge_sort(T,T), которую я загрузил во время выполнения. Если я реализую что-то вроде реестра или системы регистров, чтобы пользователи первого sort(T,T) могли переназначить себя для использования новой функции merge_sort(T,T) и определить, когда все пользователи настроились, я тогда смогу освободить и удалить sort(T,T) из памяти.

По сути, это очень похоже на JIT, но для меня привлекательной частью был аспект, в котором вы можете произвольно заменять код во время выполнения для модулей. Таким образом, пока система не находится под полной нагрузкой, когда используется каждый модуль, модули могут быть автоматизированы для переключения на новый код, если это необходимо, и т. д. Теоретически, не будет ли это способом реализации патчей таким образом, чтобы пользователь, который использует программу, никогда не должен перезапускать программу, если программа может молча заменять код в отдельных модулях? Я полагаю, что гораздо более крупные распределенные системы могут использовать это, но как насчет более мелких?


person CinchBlue    schedule 15.12.2015    source источник


Ответы (1)


Кроме того, некоторые языки, такие как Erlang, могут иметь распределенную систему, так что каждая часть отделена друг от друга, а это означает, что в случае сбоя одной из них другие могут учитывать такой случай модульным образом, а это означает, что модули также могут включаться и отключаться. по желанию, если им правильно управлять, не нарушая общего исполнения.

Вы описываете, как создать отказоустойчивую систему, которая полностью отличается от замены кода во время выполнения (известно на Динамическое обновление ПО или DSU). Действительно, в Erlang вы можете иметь один процесс, контролирующий другие процессы, и в случае сбоя одного из них он перенесет работу в другой процесс, чтобы система работала должным образом. Обратите внимание, что DSU не используется для реализации отказоустойчивости. Это разные функции с разными целями.

Скажем, у меня есть функция sort(T, T), которая работает с T или T. Теперь предположим, что у меня есть функция merge_sort(T,T), которую я загрузил во время выполнения. Если я реализую что-то вроде реестра или системы регистрации, чтобы пользователи первого вида (T, T) могли переназначить себя для использования новой функции merge_sort (T, T) и определить, когда все пользователи настроились, я тогда смогу чтобы освободить и удалить sort(T,T) из памяти.

Это называется DSU и используется для выполнения любой из следующих задач без необходимости отключения системы:

  • Исправьте одну или несколько ошибок в фрагменте кода.
  • Залатать дыры в безопасности.
  • Используйте более эффективный код.
  • Развертывание новых функций.

Таким образом, любое приложение или система могут использовать DSU, чтобы выполнять эти задачи без перезагрузки.

Erlang позволяет выполнять DSU в дополнение к отказоустойчивости, поскольку обсуждалось выше. Для получения дополнительной информации см. этот документ по написанию Erlang.

Существует множество способов реализации DSU. Поскольку вы интересуетесь компиляторами JIT и предполагаете, что под «компилятором JIT» вы подразумеваете компонент, который не только компилирует код IL, но также выделяет исполняемую память и исправляет вызовы функций с адресами двоичного кода, я расскажу, как реализовать DSU в JIT. среды. Компилятор JIT должен поддерживать следующие две функции:

  • Возможность получать или создавать новый двоичный код во время выполнения. Если у вас есть IL-код, пока нет необходимости выделять исполняемую память, поскольку ее нужно скомпилировать.
  • Возможность замены фрагмента кода IL (который, возможно, уже был подвергнут JIT-компиляции) или двоичного кода новым фрагментом кода.

Очевидно, что с этими двумя функциями вы можете выполнять DSU для одной функции. Замена всего модуля или библиотеки требует замены всех функций и глобальных переменных, экспортируемых этим модулем.

person Hadi Brais    schedule 01.01.2016