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

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

Итак, например, Python и Java имеют VM, C и Haskell этого не делают. (Исправьте меня, если я ошибаюсь)

Размышляя о том, какие языки на обеих сторонах линии, я не могу найти причину. Java статична во многих отношениях, в то время как Haskell предоставляет множество динамических функций.

4b9b3361

Ответ 1

Забудьте о виртуальных машинах в течение секунды (мы вернемся к тем ниже, я обещаю) и начните с этого важного факта:

C не содержит сборку мусора.

Для языка, предоставляющего сборку мусора, должна быть какая-то "среда выполнения/runtime-environment/thing, которая будет выполнять ее.

Для чего Python, Java и Haskell требуют "runtime" , а C, который этого не делает, могут просто скомпилировать собственный код.

Обратите внимание, что psyco был оптимизатором Python, который скомпилировал код Python для машинного кода, однако многие из этого машинного кода состояли из вызовов к функциям выполнения C-Python, таким как PyImport_AddModule, PyImport_GetModuleDict и т.д.

Haskell/GHC находится в аналогичной лодке с psyco-скомпилированным Python. Инты добавляются как простые машинные команды, но более сложные вещи, которые выделяют объекты и т.д., Вызывают время выполнения.

Что еще?

C не имеет "исключений"

Если бы мы добавляли исключения из C, наш сгенерированный машинный код должен был бы делать некоторые вещи для каждой функции и для каждого вызова функции.

Если мы затем добавим "закрытие", будет добавлено больше материала.

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

Итак, теперь каждая исходная строка источника сопоставляет некоторые вызовы некоторым функциям и меньшую уникальную часть.

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

Здесь идея (btw позволяет назвать эту идею "виртуальной машиной" ).

Обозначим ваш код Python, например:

def has_no_letters(text):
  return text.upper() == text.lower()

Как структура данных в памяти, например:

{ 'func_name': 'has_no_letters',
  'num_args': 1,
  'kwargs': [],
  'codez': [
    ('get_attr', 'tmp_a', 'arg_0', 'upper'),  # tmp_a = arg_0.upper
    ('func_call', 'tmp_b', 'tmp_a', []),  # tmp_b = tmp_a() # tmp_b = arg_0.upper()
    ('get_attr', 'tmp_c', 'arg_0', 'lower'),
    ('func_call', 'tmp_d', 'tmp_c', []),
    ('get_global', 'tmp_e', '=='),
    ('func_call', 'tmp_f', 'tmp_e', ['tmp_b', 'tmp_d']),
    ('return', 'tmp_f'),
  ]
}

Теперь напишите интерпретатор, который выполняет эту структуру данных в памяти.

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

Преимущества виртуальных машин над прямыми текстовыми интерпретаторами

  • Система VM дает вам все синтаксические ошибки перед выполнением кода.
  • При оценке цикла система VM не анализирует исходный код при каждом запуске.
    • Создание виртуальной машины быстрее, чем прямой интерпретатор текста.
    • Таким образом, прямой интерпретатор работает медленнее с длинным именем переменной и быстрее с короткими именами переменных. Это побуждает людей писать дрянной код в стиле математика, например wt(f, d(o, e), s) <= th(i, s) + cr(a, p * d + o)

Преимущества VM для компиляции машинного кода

  • Структура данных в памяти, описывающая программу, или "код VM", вероятно, будет гораздо более компактной, чем полный машинный код с полным набором кода, который снова и снова будет делать одни и те же вещи для каждой исходной строки кода. Это заставит систему VM работать быстрее, потому что из памяти потребуется извлечь меньше "инструкций".
  • Создание виртуальной машины намного проще, чем создание компилятора для машинного кода. Возможно, вы можете сделать это сейчас, даже не зная сборки/машинного кода.

Ответ 2

Это не имеет никакого отношения к статическому или динамическому.

Скорее, он станет независимым от базовой аппаратной платформы ( "строить один раз, работать везде" - теоретически...)

Собственно, это не имеет никакого отношения к языку. Можно написать компилятор C, который генерирует байт-код для JVM. Можно написать компилятор Java, который генерирует машинный код x86.

Ответ 3

Виртуальная машина (Virtual Machine) на самом деле является инструментом для разработчика языка, чтобы избежать некоторой сложности при написании языка.

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

В этой спецификации обычно вы определяете, как работают процессор/процессоры, как работает память, какой барьер чтения/записи и т.д., и более простой язык ассемблера для взаимодействия с ним.

Конечный язык обычно переводится (скомпилирован) из текстовых файлов, которые вы пишете, в представление, написанное для этой машины.

Это имеет некоторые преимущества:

  • вы отделяете язык от специфическая архитектура оборудования.
  • обычно позволяет вам контролировать, что происходит
  • разные люди могут подключаться к другой архитектуре.
  • У вас есть дополнительная информация, позволяющая оптимизировать код.
  • и др.

Существует также фактор прохлады: Посмотрите Ма, я создал виртуальную машину:).

Ответ 4

Из записи wikipedia на Виртуальные машины:

"Виртуальная машина (VM) представляет собой программную реализацию машины (то есть компьютера), которая выполняет такие программы, как физическая машина".

Наибольшим преимуществом виртуальных машин является, теоретически, переносимость кода - "пишется один раз, запускается где угодно"

Вероятно, самым известным примером виртуальной машины является JVM, изначально предназначенный для запуска Java-кода, но теперь также все чаще используется для langauges, таких как как Clojure и Scala.

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

Ответ 5

Там нет "необходимости", любой из этих языков предоставляет компиляторы, которые непосредственно испускают машинный код для реализации семантики их языка в данной архитектуре.

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

Ответ 6

Java и python могут быть скомпилированы таким образом, чтобы поддерживать независимость платформы. Это справедливо даже для С#. Преимущества заключаются в том, что виртуальные машины могут преобразовывать этот, в основном, строго типизированный байт-код, в очень хороший код на платформе с низкими накладными расходами relativ. Так как Java предназначена для "сборки один раз - когда-либо", JVM был создан.

Ответ 7

Виртуальная машина - это в основном интерпретатор, который интерпретирует язык ближе к машинным кодам. Когда реальная машина интерпретирует настоящий машинный код, виртуальная машина интерпретирует готовый машинный код. Некоторые машинные коды VM-интерфейса реального компьютера - они называются эмуляторами.

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

В основном, как большинство языков в наши дни (которые не скомпилируются до реального машинного кода).

Интерпретатор (VM) и компилятор могут быть либо отдельными программами (например, java и javac), либо они могут быть только одной программой (например, с Ruby или Python).

Ответ 8

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

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

Теперь для дополнительных точек создайте формат байт-кода для сериализации вашего представления в памяти и загрузчика во время выполнения или, если вы хотите перейти на язык сценариев, eval().

Для грандиозного финала добавьте JIT.