Как работает виртуальная машина? - PullRequest
18 голосов
/ 30 мая 2009

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

При условии, что я это сделал, меня сбивает с толку то, что многие некомпилированные языки допускают переменные с "либеральными" системами типов. В Python, например, я могу написать это:

x = "Hello world!"
x = 2**1000

Строки и большие целые числа совершенно не связаны и занимают различное количество места в памяти, так как же этот код может быть представлен даже в стековой среде? Что именно здесь происходит? X указывает на новое место в стеке, а старые строковые данные остаются без ссылок? Разве эти языки не используют стек? Если нет, то как они представляют переменные внутри?

Ответы [ 5 ]

7 голосов
/ 30 мая 2009

Вероятно, ваш вопрос должен быть озаглавлен как "Как динамические языки работают?"

Все просто, они хранят информацию о типе переменной вместе с ней в памяти. И это делается не только на интерпретируемых или JIT-скомпилированных языках, но и на скомпилированных на родном языке, например Objective-C.

2 голосов
/ 30 мая 2009

ВМ не имеет ничего общего с языком. Любой язык может работать поверх ВМ (в Java ВМ уже есть сотни языков).

ВМ позволяет запускать другой тип «ассемблера», более подходящий для адаптации компилятора. Все, что делается в ВМ, может быть сделано в ЦП, поэтому думайте о ВМ как о ЦП. (Некоторые на самом деле реализованы аппаратно).

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

С обычными скомпилированными языками для одного шага требуется много инструкций. a + может выглядеть как «Схватить элемент из точки относительно указателя стека в reg a, перехватить другой в reg b. добавить reg a и b. поместить reg a в место относительно указателя стека.

ВМ делает все это с помощью одной короткой инструкции, возможно, одного или двух байтов вместо 4 или 8 байтов НА ИНСТРУКЦИЮ на машинном языке (в зависимости от 32 или 64-битной архитектуры), что (предположительно) должно означать около 16 или 32 байты x86 для 1-2 байтов машинного кода. (Я могу ошибаться, мое последнее кодирование x86 было в эпоху 80286.)

Microsoft использовала (вероятно, до сих пор) виртуальные машины в своих офисных продуктах, чтобы уменьшить объем кода.

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

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

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

http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html

2 голосов
/ 30 мая 2009

В большинстве языков ВМ переменные могут быть концептуализированы как указатели (или ссылки) на память в куче, даже если сама переменная находится в стеке. Для языков, которые имеют примитивные типы (например, int и bool в Java), они также могут храниться в стеке, но им нельзя назначать новые типы динамически.

Игнорируя примитивные типы, все переменные, которые существуют в стеке, имеют свои фактические значения, сохраненные в куче. Таким образом, если вы динамически переназначаете им значение, исходное значение отбрасывается (и память очищается с помощью некоторого алгоритма сборки мусора), и новое значение выделяется в новом бите памяти.

1 голос
/ 30 мая 2009

Чтобы ответить на часть ваших вопросов, я бы порекомендовал техническую беседу google о python , где даны ответы на некоторые из ваших вопросов, касающихся динамических языков; например, что такое переменная (это не указатель и не ссылка, а в случае с python метка).

1 голос
/ 30 мая 2009

Ключ ко многим из того, «как виртуальные машины обрабатывают переменные, подобные той или иной», в действительности сводится к метаданным ... Сохраненная и затем обновленная метаинформация дает виртуальной машине гораздо лучший способ распределить, а затем выполнить правильно с переменными.

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

Что касается ваших конкретных вопросов - обработка переменных как ванильных объектов / и т. Д. ... сводится к переназначению / переоценке метаинформации для новых назначений - вот почему x может смотреть в одну сторону, а затем в другую.

...