Базовой единицей каких виртуальных машин является машинная инструкция

Два мира виртуальных машин

Время на прочтение
18 мин

Количество просмотров 36K

Виртуальный. В отличие от большинства модных компьютерных словечек, это понятие обычно соответствует своему словарному определению в тех случаях, когда речь идёт об аппаратуре или программах. Словарь «Random House College Dictionary» определяет «virtual» как «проявляющий свойства и эффекты чего-либо, но не являющийся таковым на самом деле».

Оригинал

Virtual. Unlike most computer buzzwords, this one usually holds true to its dictionary definition when it refers to hardware or software. The Random House College Dictionary defines «virtual» as «being such in force or effect, though not actually or expressly such.» [4]

Последние несколько лет в начале каждого семестра я даю студентам определения основных терминов, используемых в моём курсе: симуляция, эмуляция и виртуализация. И каждый раз я говорю, чтобы мои слова не принимали за стопроцентную правду. Дело в том, что в одних областях технического знания эти термины зачастую трактуются противоположно тому, что принято использовать в других. Нелёгкое это дело — давать определения.

Видимо, эту проблему заметил не только я. В своей книге Software and System Development using Virtual Platforms, вышедшей в прошлом году, мои коллеги Jakob Engblom и Daniel Aarno в первой главе вводят понятия simulation и emulation и отмечают неоднозначность их толкования в областях разработки программного обеспечения и проектирования аппаратуры.

С беспорядком в толковании этих двух терминов я для себя разобрался и вроде бы смирился. Осталось ещё одно понятие, уже более десяти (на самом деле пятидесяти) лет не теряющее популярности — это «виртуализация». За время своего бытия в категории «buzzword» оно стало сочетаться со множеством других слов. Недавно я осознал, что термин «виртуальная машина» (ВМ) на самом деле используется для обозначения двух хоть и связанных, но различных сущностей. В этой статье я расскажу о двух классах: языковые и системные виртуальные машины. Я покажу сходства и различия между ними, их назначение, классификацию, общие и частные черты в их практической реализации.

Если говорить широко, то виртуальная машина — это программа, задача которой состоит в реализации спецификаций определённого вычислительного устройства или класса устройств. В этом её главное отличие от «просто» физической машины, реализующей то же самое, но в аппаратуре. Всякая спецификация (архитектура компьютера) чаще всего включает в себя определение интерфейсов устройств и описание переходов между состояниями машины. Однако определение интерфейса, как известно, не должно налагать ограничений на способы его реализации.

Многие из нас, наверное, не замечают, как часто ежедневно они сталкиваются с обеими типами машин — виртуальными и реальными. Например, самый простой калькулятор имеет две реализации — как специализированное устройство и как программа:

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

Виртуальный калькулятор — это пример виртуальной машины — программной копии того, что изначально существовало только в виде аппаратуры, физической машины, вполне конкретной и осязаемой системы. К системным ВМ мы вернёмся чуть позже.

Языковые ВМ

Другой случай — это когда программа создаётся для чего-то «нереального» с самого начала, например, для языка программирования или среды исполнения (runtime environment). В этом случае такая языковая виртуальная машина будет способом реализации спецификации языка или среды.

Всегда ли нужна ВМ?

Ключевая фраза в предыдущем параграфе — способ реализации. Кроме ВМ, есть и другие способы.
Всякий раз, когда мы берём в руки документацию на новый язык программирования, мы открываем описание «несуществующей» машины. Например, K&R Си — это во многих своих местах нарочно недосказанное описание среды для программ на Си. Большинство реализаций Си являются компиляторами (буду благодарен, если мне подскажут реализации, основанные на ВМ). Для Java описание среды и её границ более чёткое (у её авторов были иные цели и задачи, чем у создателей Си), однако и здесь не диктуется ни использование какой-то конкретной ВМ (на выбор машины от Sun/Oracle, IBM, Microsoft, Apple, GNU и даже Dalvik от Google), ни даже необходимость в ВМ (компилятор GNU GCJ).

Языковые ВМ обычно проектируются для исполнения одного гостевого приложения (иногда многопоточного) в одной копии виртуальной среды. Другими словами, они не берут на себя типичные для многопользовательской/многозадачной операционной системы функции разграничения доступа к ресурсам. Задача языковой ВМ — предоставить программе окружение, напрямую не зависящее от деталей (и в какой-то мере ограничений) нижележащей физической системы, таких как используемые в последней процессоры, объёмы ОЗУ и дисков, наличие и особенности периферийных устройств и т.д.

Конечно же, и тут не обойтись без холивара про терминологию. К языковым ВМ (language VMs) я буду относить и то, что называется process virtual machine, и то, что именуется managed runtime environment (MRE).

Два семейства языковых ВМ

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

Базовой единицей исполнения для ВМ является машинная инструкция. Каждая такая инструкция должна определять операцию, выполняемую над данными, а также местоположение самих данных. Естественно, что набор операций сильно зависит от конкретной ВМ и может варьироваться в широких пределах. «Железные» наборы инструкций в этом куда более ограничены [Я всё ещё жду процессор с аппаратными malloc() и free(), а лучше — с аппаратным сборщиком мусора].
С другой стороны, в подходах к организации обрабатываемых данных среди ВМ не так много разнообразия. Фактически есть две устоявшиеся концепции — хранить данные на стеке (стеках) и использовать выделенный набор регистров.

Стековые ВМ

Такие ВМ хранят все или почти все данные в одном или нескольких стеках. Для обращения к ним используется адресация относительного положения требуемой ячейки от текущей вершины стека. Если у операции есть результат, то он помещается в стек, становясь его новой вершиной. Кроме данных, в стеке могут храниться адреса, используемые при возврате из вызванных подпроцедур в вызывающие. Или же адреса могут быть в отдельном стеке.
Про стековые машины известно и написано много, и я не буду пытаться здесь описать всё, что знаю и чего не знаю. Выделю лишь некоторые ключевые факты.

Отмечу достоинства стековых языковых ВМ:

  • Простота трансляции выражений из инфиксной нотации (выражения со скобочками: a + b * (c / (d - f))) в стековое представление (обратную польскую запись).
  • Компактность кодировки инструкций. Большинство машинных команд не требуют явных аргументов, так как они работают с вершиной стека.

Единственное важное на практике исключение — это передача в процесс вычисления литералов — констант. Их легче передать целиком в потоке инструкций, чем пытаться «сконструировать» из добра, уже хранящегося на стеке. Но при желании можно сделать ВМ и без этого: завести операцию «положить в стек единицу», а дальше складывать её с собой до получения нужного числа.
Нельзя сказать, что в стековой ВМ совсем не может быть выделенных регистров. Как минимум две ячейки иметь приходится: одну для указателя текущей команды, а другую — для указателя на вершину стека. Однако они не всегда доступны для прямой манипуляции в программе, т.е. не каждая машина делает их архитектурно видимыми.

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

Примеры

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

Исторические важные примеры стековых языковых ВМ

SECD — абстрактная машина, появившаяся в 1960-х годах и повлиявшая на развитие функциональных языков, в том числе LISP.

P-code — язык виртуальной машины, в который транслировал программы первый компилятор Паскаля университета Калифорнии. Благодаря переносимости p-code и подхода с «самораскруткой» (bootstrapping) компилятора имелась возможность достаточно быстро получить работающий компилятор Паскаля на новых ЭВМ, что во времена отсутствия стандартов на окружение (никаких тебе POSIX в 70-х) и огромного числа несовместимых между собой архитектур ЭВМ было важным фактором для завоевания языком популярности.

Forth — вообще-то Forth нельзя назвать только языковой ВМ. Для кого-то это процедурный язык высокого уровня, для кого-то объектно-ориентированный язык, кому-то — функциональный, кому-то — машинный, а кому-то и вовсе философия проектирования систем (Thinking Forth). Однако именно Форт приходит мне на ум, когда кто-то произносит слова «программирование» и «стек» в одном предложении.

Актуальные языковые ВМ

Java VM — байткод для всем известного «compile once, run everywhere» языка Java (а также для Scala, Clojure и др.) выполняется на стековой ВМ. Сам стек хранит скалярные данные выполняющихся методов, аргументы инструкций, в том числе ссылки на объекты и массивы, которые хранятся в отдельной области-куче.

Common Intermediate Language от Microsoft — основание .NET-фреймворка. В него транслируются C#, F#, VB.NET и множество других менее популярных языков высокого уровня. Байткод выполняется на стековой ВМ. Структура как среды выполнения, так и байткода CIL существенно отличается от JVM; в [1] приводится их сравнение, в том числе показываются их сходства между собой и отличия от обычных аппаратных наборов инструкций.

Таким образом, две самые популярные среды времени исполнения используют стековые языковые ВМ. Возможно, у читателя возник вопрос: если код из байткода чаще всего в конце концов транслируется в настоящий машинный код хозяйской системы, архитектура которой содержит регистры, а не только стек (кто читает эти строки с дисплея машины со стековой машинной архитектурой — поднимите руки!), то почему две самых популярных языковых ВМ используют стековое представление? В [1] приводится следующий довод: «…a stack is amenable to platform independence (the host platform can have any number of registers in its ISA)» — «стек облегчает обеспечение платформонезависимости (хозяйская платформа может иметь любое количество регистров в своём наборе команд)».

Регистровые ВМ

Альтернативный подход к хранению обрабатываемых данных состоит в использовании выделенного набора ячеек памяти с фиксированными именами-номерами — регистрами. Инструкции в основном оперируют с данными на регистрах, при необходимости загружая отсутствующие значения из памяти или выгружая ненужные в память.
В некоторых регистровых архитектурах стек тоже обычно имеется в наличии. Однако он не играет центральной роли в работе ВМ, а используется для поддержки процедурного механизма (и в таком случае не обязательно является напрямую доступным программам).

Особенности регистровых ВМ проще всего увидеть, сравнивая их со стековыми.

  • Их машинные инструкции длиннее, так как в них приходится кодировать операнды. В стековых ВМ операнды задаются неявно.
  • При работе ВМ происходит меньшее число обращений к памяти. Стековые ВМ вынуждены постоянно перекладывать данные на стеке, так как время жизни последних невелико (чаще всего операция «съедает» входные значения с вершины стека и замещает их своим результатом). Значение, помещённое в регистр, живёт до момента его перезаписи. Например, это позволяет избавиться от постоянного вычисления или подгрузки из памяти значений для цикловых инвариантов — они просто размещаются в регистрах.
  • Необходимость использования алгоритмов распределения регистров при трансляции с языков высокого уровня. Для нетривиальных программ всегда будет возникать ситуация нехватки регистров (их число ограничено) для размещения всех используемых при вычислении данных. При этом как-то надо следить, на каком регистре что находится в каждый момент времени. Тогда как в случае стековых ВМ вершина стека одна, и она всегда «доступна». Эти обстоятельства могут значительно усложнять логику работы инструментов для регистровой ВМ.

Интереснейший вопрос заключается в том, какой тип ВМ — стековый или регистровый — исполняет программы быстрее. Однозначного ответа к настоящему моменту нет; данные одних исследователей доказывают преимущество первого вида, тогда как остальные утверждают обратное. Интересный эксперимент описан в [3] — авторы статьи используют для исполнения регистровую ВМ, код для которой получается с помощью оптимизирующей трансляции из Java байткода, и сравнивают производительность.

Примеры

Parrot VM —

долгострой

ВМ, разрабатываемая уже более 10 лет и служащая основной средой исполнения языка Perl 6.

Dalvik от Google — регистровая ВМ, служащая для исполнения приложений, написанных на Java. Интересно, что байткод стековой JVM (*.class) преобразуется в байткод регистровой ВМ (*.dex). В настоящее время Dalvik отходит на второй план в Android, уступая место ART — механизму прямой компиляции в машинный код хозяйской системы.

LLVM bitcode — одно из представлений исходной программы, используемое при трансляции программ с помощью инструментов на основе LLVM, и по совместительству входной язык ВМ, использующий трёхоперандный формат инструкций с регистрами. Необычным в этой ВМ является то, что инструкции выражены в т.н. SSA (single static assignment) форме, т.е. они используют потенциально неограниченное число виртуальных регистров. Распределение регистров ВМ на физические происходит позже в процессе трансляции в машинный код или интерпретации.

MIX и MMIX — виртуальные машины, используемые (или планируемые к использованию в будущих изданиях) Д. Кнутом в своей серии книг «Искусство программирования» для иллюстрации реализации алгоритмов. MIX выполнена в духе 1960-х: выделенный регистр-аккумулятор, 6-битные байты, двоично-десятичный формат чисел, отсутствие стека и склонность к задействованию самомодифицирующегося кода. MMIX — это уже вменяемый RISC с щедрым числом (256) и шириной (64 бит) регистров.

Об иллюстрации алгоритмов машинным кодом

Лично мне очень сложно понять «алгоритмы», написанные на MIX, в и без того сложной книге несомненно уважаемого мной автора. Мне почему-то кажется, что использование языков более высокого уровня значительно облегчило бы восприятие.

Экзотические ВМ

Остерегайтесь смоляной ямы Тьюринга, в которой всё возможно, но ничто из интересного не достижимо.

Оригинал

Beware of the Turing tar-pit in which everything is possible but nothing of interest is easy. Alan Perlis, «Epigrams on Programming»

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

printf() как виртуальная машина — не совсем экзотика, просто хочу показать знакомую многим вещь под новым углом. Ведь если присмотреться, то строка спецификации, идущая первым аргументом у стандартных функций семейства printf языка Си — это программа, инструкциями которой являются символы, а данными — оставшиеся аргументы функции. Большинство инструкций этой ВМ просто выводят один символ, совпадающий с кодом самой инструкции; но вот инструкция % имеет гораздо более сложную семантику, зависящую от следующих за ней символов. Неудивительно, что некоторые уязвимости в ПО основаны на передаче специально подобранной строки для интерпретации её в printf и исполнения неавторизованного кода.

OISC. Самый увлекательный и загадочный (для меня) класс языков экзотического типа — это OISC (one instruction set computer) — системы, содержащие ровно одну машинную инструкцию и при этом не являющиеся совсем тривиальными. Некоторые из них эквивалентны машине Тьюринга, т.е. на них могут быть запрограммированы достаточно сложные алгоритмы. Самая известная из OISC — subleq (subtract and branch unless positive).
Следует отметить, что OISC зачастую скрывается во вполне привычном наборе машинных инструкций; например, MOV в PDP-11 или #PF/#DF в составе Intel ® IA-32; последнюю машину можно назвать zero instruction set computer, потому что формально исполнения инструкций IA-32 при обработке исключений не происходит.

Dis — ВМ для распределённой ОС Inferno, созданной в Bell Labs людьми, стоявшими у истоков ОС Plan 9. Эта машина имеет адресацию «память-память», что довольно необычно по современным меркам (последний раз в аппаратуре такое было в Motorola 68000), и отсутствие архитектурно видимых регистров. Я не могу придумать преимуществ такого подхода ни перед регистровыми, ни перед стековыми системами; скорее, он собирает в себе все их недостатки.

Способы исполнения

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

Интерпретация — основная и первоначальная техника как для языковых, так и для системных ВМ. Базовый принцип её я описывал в предыдущих своих статьях. Вопрос построения максимально эффективного интерпретатора не так прост, как кажется, и имеет большую практическую ценность из-за широкой популярности и распространённости динамических языков, использующих интерпретацию на различных этапах своей работы. И далеко не всегда достаточно написать switch (...) {case ... case ... case ...}. Я планирую поподробнее описать проблемы, приводящие к низкой скорости работы для такого наивного подхода, и существующие решения в одной из последующих своих статей.

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

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

Заинтересовавшимся вопросами проектирования и реализации языковых ВМ я могу посоветовать книгу [2], автор которой описывает теорию и приводит практические примеры реализации стековых, регистровых ВМ, а также «экзотического» варианта ВМ для событийно-ориентированной системы.

Системные ВМ

Системные виртуальные машины, как правило, создаются по спецификациям, для которых уже существуют «железные» реализации. Это привносит свои особенности в процесс создания таких ВМ. Архитектура настоящей аппаратуры ограничена сильнее чисто программной, «умозрительной» ВМ: влияют требования на производительность, энергопотребление, физические размеры кристалла, способного вместить реализацию, совместимости с внешними устройствами и т.д.

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

В отличие от создателей языковых ВМ, которые часто имеют довольно большую свободу при выборе деталей машинного языка, программисты, реализующие системные ВМ, связаны необходимостью чётко следовать спецификациям на аппаратуру, которые обычно нелегко изменить. Значительные усилия приходится тратить на эффективную поддержку идиосинкразий (или попросту костылей) выбранного машинного языка. После длительной эволюции и многочисленных расширений некоторые архитектуры и вовсе выглядят как сплошной забор из костылей… но я отвлёкся. В любом случае, при создании системной ВМ больше внимания достаётся вопросам создания корректной и быстрой программы, чем хлопотам о входном машинном языке.

Классификация системных ВМ

Системные ВМ в первую очередь классифицируются по тому, какой тип гостевого процессора моделируется. Классификаций процессоров существует много, и они довольно подробно описаны в различных источниках, поэтому здесь лишь кратко резюмирую самые общие вещи. По архитектуре набора команд ЦПУ бывают CISC — сложные инструкции, делающие сразу много вещей сразу, включая загрузку данных из памяти, и RISC — максимально простые инструкции, в которых доступ к памяти и операции над данными в регистрах явно разделены; несколько особняком стоят VLIW, в которых несколько разных операций объединяются в одно машинное слово. Также можно классифицировать наборы команд по признаку вариативности длины инструкции: системы с переменной длиной команд и системы с фиксированной длиной. По правде сказать, по-настоящему постоянная длина инструкций встречается редко — всегда или что-то не влезает в машинное слово (например, 32-битные литералы в ARC и 64-битные в IA-64), или же создатели пытаются сэкономить, назначая для часто используемых инструкций последовательности покороче (16-битные команды ARCompact или ARM Thumb).

При создании системной ВМ важным классификационным признаком является наличие/отсутствие отношений «родства» между архитектурами хозяйской и гостевой систем. По степени родства моделируемая и моделирующая системы могут быть: полностью разнородными (например, Zilog Z80 и PowerPC), похожими (Intel IA-32 и Intel 64, или Intel 8086 и Intel IA-32) или же совпадающими (X и X, где X — ваша любимая архитектура).

В случае, когда гость и хозяин различны, задача системной ВМ состоит в обеспечении возможности запуска приложений, написанных и скомпилированных для «чужой» архитектуры, на хозяйской системе без необходимости их перекомпиляции или какой-либо ещё модификации. В идеале программная прослойка ВМ может быть вообще невидимой для конечного пользователя. Она обязана работать корректно, достаточно быстро и не требовать дополнительной конфигурации.

Такой подход может помочь компаниям перевести пользователей с их любимыми программами со своей старой архитектуры на новую (конечно же, превосходную во всём, но несовместимую со старой), или же переманить пользователей систем конкурента на собственную. Системная ВМ при этом должна устранить цикл: новая архитектура — нет приложений — нет пользователей — нет разработчиков — нет популярности — нет приложений.
Примеров такому применению ВМ масса. Приведу некоторые известные мне.

  • Компания Digital: Digital FX!32 для запуска приложений IA-32 на Alpha, VEST — для запуска программ VAX на Alpha, mx — Ultrix MIPS на Alpha.
  • Компания IBM: PowerVM Lx86 для запуска IA-32 на процессорах POWER.
  • Apple использовала системные ВМ дважды: при переходе с Motorola 680×0 на PowerPC в 1996 году; Apple Rosetta для перевода с PowerPC на IA-32 в 2006 году.
  • Российская компания МЦСТ разработала ПО для обеспечения запуска операционных систем и программ IA-32 на процессорах «Эльбрус».
  • Компания Intel создала программный IA-32 Execution Layer для запуска IA-32 приложений на Intel Itanium.
  • Подсистема NTVDM (NT virtual DOS machine) в 32-битных версиях Microsoft Windows использовалась для исполнения DOS-приложений, ожидающих увидеть процессор 8086 в реальном режиме под управлением MS-DOS.
  • И ещё раз Intel: для запуска приложений для Android, скомпилированных для архитектуры ARM, на телефонах от с Intel Atom, также была создана программная прослойка, невидимая для пользователя.

Конечно же, этот список можно продолжить.

В случаях совпадения архитектур систем гостя и хозяина системные ВМ также находят применение. Запуск гостевой ОС внутри ВМ под управлением монитора позволяет контролировать потребление ею ресурсов, исполнять одновременно с другими системами, замораживать, восстанавливать из образов, клонировать, мигрировать с одного места на другое и вообще выполнять разные фокусы, которые затруднительно провернуть с ОС, запущенной напрямую на железе.

Для создателей ВМ критично важным становится свойство «виртуализуемости» набора команд. От того, удовлетворяет ли выбранная архитектура машинных команд достаточным условиям Голдберга-Попека, зависит, насколько просто будет реализовать монитор виртуальных машин для неё, а также насколько серьёзное замедление (по отношению к работе на «голом» железе) он будет вносить. Intel IA-32/Intel 64 до появления расширений Intel VT-x принадлежала к первой категории сложно-виртуализуемых систем, но в настоящее писать эффективные мониторы для неё «легко» (если это слово применимо к разработке модулей ядра для набора команд с почти полувековой эволюцией).

Способы исполнения

С точки зрения программной реализации системные ВМ имеют много общего с языковыми. Это неудивительно — базовая единица исполнения в обоих случаях — машинная инструкция.

Интерпретация — и снова это слово! В случае, когда нужно сделать максимально легко портируемую системную ВМ без особой оглядки на скорость, интерпретатор будет естественным первым выбором. Bochs — наверное, самый известный из открытых проектов такого типа. Подчеркну вновь отсутствие порядка в терминологии — на официальной странице Bochs представлен как «PC emulator», а не симулятор или виртуальная машина.

Динамическая трансляция — как было описано ранее, группа технологий, обещающих более высокую скорость работы. А вот статическая трансляция, применимая для языковых ВМ, не очень удобна для создания ВМ системных — в полноплатформенных моделях крайне редко весь код доступен и известен заранее, до начала симуляции. К чисто динамическим трансляторам относится ранее упомянутый IA-32 Execution Layer.

Аппаратная поддержка — для архитектур, поддерживающих виртуализацию аппаратно, это наиболее эффективный метод. Однако он и самый «капризный», ведь он работает только при совпадении архитектур гостя и хозяина. Часто даже относительно небольшие различия между наборами расширений выбранных систем могут сделать нецелесообразными попытки создания ВМ такого типа. Большинство современных коммерческих гипервизоров для IA-32 активно полагаются на наличие VT-x в своей работе.

Заинтересовавшимся вопросами проектирования и реализации системных ВМ я хочу посоветовать книгу [1]. Незаинтересовавшимся тоже рискну её посоветовать — в ней доступно объясняются многие важные особенности компьютерной архитектуры, она написана довольно понятным языком.

Что появилось раньше — виртуальная память или виртуальная машина?

Хочу поделиться удивительным для меня фактом. В те далёкие времена, когда ещё шли дебаты о том, стоит ли включать аппаратную поддержку страничной виртуальной памяти в коммерческие ЭВМ или же ей место лишь в немногиз экспериментальных или узкоспециализированных системах, аппаратные виртуальные машины уже вовсю использовались для разработки программ. Более того, они даже «продавались» для консолидации задач нескольких независимых потребителей машинного времени на одной физической системе. В [4], книге об основах работы в операционных системах для мэйнфреймов, есть примечательный параграф:

IBM разработала операционную систему VM (Virtual Machine) в 1964. Как и любая ОС, VM контролировала ресурсы компьютера. Она также предоставляла новую возможность, никогда не существовавшую раньше в других ОС: иллюзию для каждого пользователя, что в его распоряжении есть целый компьютер, полностью для его нужд. IBM создала VM задолго до появления идеи персонального компьютера, и в то время возможность иметь хотя бы симуляцию компьютера целиком и полностью для себя самого было Большим Делом. Если двадцать человек подключились к системе с VM одновременно, она создаёт для каждого из них иллюзию, что они используют двадцать различных независимых компьютеров.

Оригинал

IBM developed VM («Virtual Machine») in 1964. Like any operating system, VM controlled the computer’s resources. It also added a feature that had never existed before: the illusion, for each of its users, that they had a whole computer to themselves. (Because IBM developed VM well before the invention of the PC, having even a simulation of your own computer was a Big Deal.) If twenty people use a VM system at once, it gives them the illusion that they are using twenty different computers.

Другими словами, системные виртуальные машины старше виртуальной памяти!

Итоги

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

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

Уфф, как всегда, хотел написать пару строк, а получилась длинный пост-простыня.

Конечно, область вопросов о структуре, производительности и развитии виртуальных машин необъятна. Я планировал написать ещё о паре моментов в работе создателей ВМ, но, пожалуй, отложу их на следующий раз.
Спасибо за внимание!

Литература

  1. James E. Smith, Ravi Nair, Virtual Machines: Versatile Platforms For Systems And Processes — Morgan Kaufmann — 2005. ISBN 1-55860-910-5
  2. Craig, Iain D. Virtual Machines — Springer — 2006. ISBN 1-85233-969-1
  3. Yunhe Shi, Kevin Casey, M. Anton Ertl, and David Gregg. Virtual Machine Showdown: Stack Versus Registers — USENIX — 2008. www.usenix.org/events/vee05/full_papers/p153-yunhe.pdf
  4. Bob DuCharme. Fake Your Way Through Minis and Mainframes (formerly, «The Operating System Hand-book») — Part 5: VM/CMS — 2001. www.snee.com/bob/opsys/part5vmcms.pdf

Е.Я. СОЙМИНА

СОЗДАНИЕ ВИРТУАЛЬНЫХ МАШИН

И

ВИРТУАЛЬНОЙ СЕТИ

Методические указания к лабораторным работам по дисциплине «Администрирование в информационных системах»

МОСКВА – 2013

Федеральное государственное бюджетное образовательное учреждение высшего профессионального образования

«Московский государственный
университет путей сообщения»

Кафедра «Автоматизированные системы управления»

Е.Я. СОЙМИНА

СОЗДАНИЕ ВИРТУАЛЬНЫХ МАШИН

И

ВИРТУАЛЬНОЙ СЕТИ

Рекомендовано редакционно-издательским советом университета в качестве методических указаний
для студентов специальностей 230400

МОСКВА – 2013

УДК 004

С 54

Соймина Е.Я. Создание виртуальных машин и виртуальной сети: Методические указания. — М.: МИИТ, 2013, — 45с.

Методические указания позволяют студентам получить знания и практические навыки по созданию виртуальных рабочей станции и сервера на базе реального компьютера, установке на них операционных систем и связывание их в виртуальную сеть. Представлены краткие теоретические сведения, последовательность действий и контрольные вопросы для лабораторных работ №1 и №2 по дисциплине «Администрирование в информационных системах».

O МИИТ, 2013

СОДЕРЖАНИЕ

СОДЕРЖАНИЕ.. 3

1. ТЕОРЕТИЧЕСКИЕ СВЕДЕНИЯ.. 4

1.1. Виртуальная машина. 4

1.2. Виртуальная сеть. 10

2. ХОД ВЫПОЛНЕНИЯ РАБОТЫ… 11

2.1 ЗАДАНИЕ №1. Установка Virtual Box. 11

2.2. ЗАДАНИЕ №2. Создание виртуальных машин: рабочей станции и сервера 13

2.3. ЗАДАНИЕ №3. Установка операционных систем.. 24

2.3.1. Установка ОС Windows XP. 24

2.3.2. Установка ОС Windows Server 2003 на ВМ.. 27

2.3.3. Установка Windows 7 на ВМ.. 29

2.3.4. Установка операционной системы Windows Server 2008. 34

2.4. ЗАДАНИЕ №4. Экспорт и импорт виртуальных машин. 36

2.4.1. Экспорт виртуальной машины.. 37

2.4.2 Импорт виртуальной машины.. 39

2.5. ЗАДАНИЕ №5. Создание виртуальной сети. 42

3. СОДЕРЖАНИЕ ОТЧЕТА.. 44

4. КОНТРОЛЬНЫЕ ВОПРОСЫ… 44

5. ЛИТЕРАТУРА.. 44

1. ТЕОРЕТИЧЕСКИЕ СВЕДЕНИЯ

Виртуальная машина

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

Набор ресурсов и правил ее работы формируется с помощью программного обеспечения.

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

Операционная система, установленная на реальном ПК, называется хостовойОС.

Операционная система, принадлежащая конкретной ВМ, называется гостевой ОС.

Основные характеристики ВМ

1. Изоляция

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

Несколько ВМ на одном ПК используют ресурсы этого ПК и при этом полностью изолированы друг от друга так, как если бы они работали на разных физических системах.

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

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

Изоляция — это одна из основных причин значительно более высокой доступности и безопасности приложений в виртуальной среде по сравнению с традиционной системой. Если на одном

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

2. Инкапсуляция

ВМ — это программный контейнер, который объединяет в себе (инкапсулирует) полную вычислительную среду:

— полный набор аппаратных ресурсов в виде виртуальных (т.е. программных) ресурсов (процессор, BIOS, ОЗУ, жесткий диск, сетевой адаптер);

— установленные операционные системы и приложения.

Даже сама ВМ считает себя «настоящим» компьютером.
Инкапсуляция делает ВМ мобильными и удобными в управлении: их можно переносить и копировать так же, как любой другой программный файл, и сохранять их на любом стандартном устройстве хранения от карманных USB-накопителей до корпоративных хранилищ SAN.

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

4. Независимость от оборудования

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

Это позволяет:

• поддерживать разнородные комбинации ОС и приложений на одном физическом ПК,

• настроить ВМ с виртуальными комплектующими, полностью отличными от физических комплектующих базовой системы.

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

Цели использования ВМ

В настоящее время ВМ широко используются для:

— защиты информации и ограничения возможностей процессов;

— исследования производительности программного обеспечения или новой компьютерной архитектуры;

— эмуляции различных архитектур (в т.ч. игровых консолей);

— оптимизации использования ресурсов высокопроизводительных компьютеров;

— управления инфицированной системой в качестве вредоносного кода;

— моделирования ИС с клиент-серверной архитектурой на одной ЭВМ (эмуляция компьютерной сети с помощью нескольких ВМ).

— упрощения управления кластерами;

— тестирования и отладки системного программного обеспечения;

— миграции с одной физической машины на другую во время работы.

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

  • экономия на аппаратном обеспечении (оптимизация использования ресурсов мейнфреймов, имитация нескольких серверов на одном реальном сервере);
  • повышение безопасности (защита информации и ограничения возможностей программ, например,обеспечивает развязку между несколькими пользователями, работающими в одной вычислительной системе);
  • создание требуемых аппаратных конфигураций
  • эмуляция необходимых устройств и различных архитектур (например, игровой приставки);
  • создание виртуальных сетей, моделирование информационных систем с клиент-серверной архитектурой
  • повышение мобильности, упрощения управления кластерами (ВМ могут мигрировать с одной физической машины на другую во время работы).
  • возможность обучения работе с операционными системами;
  • поддержка устаревших ОС и ПО;
  • организация «пакетов приложений»;
  • возможность тестирование и отладка системного ПО;
  • удобное управление виртуальными машинами
  • возможность исследованияпроизводительности ПО или новой компьютерной архитектуры.

Недостатки ВМ

• снижение надёжности реальных машин

выход из строя винчестера приведёт к неработоспособности основной ОС и всех виртуальных)

• падение производительности гостевых и главной ОС в случае полного захвата пропускной способности сети или 100%-й загрузки процессора гостевой ОС.

• возможность создания вредоносного кода для управления инфицированной системой

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

— существенно повышает эффективность и доступность ресурсов и приложений в организациях.

— сокращает совокупные ИТ-расходы на 50-70%

— поддержка нескольких ОС на одном компьютере

— выполнение Windows на компьютере Mac

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

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

— обеспечение непрерывности бизнеса благодаря усовершенствованным решениям по аварийному восстановлению.

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

Приложение ВМ или Система Виртуальных Машин– СВМ – это инструмент для создания ВМ – обычное приложение,
устанавливаемое, как и любое другое, на конкретную операционную систему.
7

В таблице даны краткие характеристики некоторых популярных приложений виртуальных машин

Таблица 1.Характеристика приложений ВМ

Монитор ВМ (МВМ)

Все задачи по управлению виртуальными машинами решает специальный модуль (программа или аппаратная схема) в составе приложения ВМ – монитор виртуальных машин (МВМ).

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

• надежную изоляцию,

• защиту и безопасность,

• разделение ресурсов между работающими ОС

• управление ресурсами.

• независимое включение, перезагрузку, выключение любой ВМ.
8

Благодаря МВМ у всех работающих на данном компьютере ОС создается иллюзия, что каждая из них является единственной. Монитор не зависит от конкретной хостовой ОС и отвечает за создание виртуальной среды для исполнения гостевой ОС. Он работает на уровне привилегий ядра хостовой ОС и реализует выбранную технологию виртуализации.

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

Для каждой виртуальной машины запускается своя копия МВМ.

Пользователь не имеет непосредственного доступа к МВМ, ему предоставляется лишь графический интерфейс.

Графический интерфейс для создания и настройки ВМ называют консолью виртуальных машин.

Виртуальная сеть

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

При этом система адресов и способ идентификации ПК несколько отличается от того, что применяется в обычной сети.

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

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

• доступ к ПК может быть определен не только адресом, но портом;

• ПК могут быть как реальными, так и виртуальными;

• виртуальные ПК могут находиться на реальных машинах как принадлежащих одной из сетей, так и не принадлежащих им;

• на каждом ПК может находиться несколько виртуальных адаптеров.
9

• каждый ПК такой сети может быть сервером и/или клиентом виртуальной сети;

• каждая пара или большая группа ПК виртуальной сети может иметь общий секретный ключ доступа;

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

• команда tracert [ip-адрес], выводящая на экран командной строки информацию о маршруте соединения, не покажет ни одного промежуточного узла между машинами, работающими в виртуальной сети.

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

Как и в реальной сети, при построении виртуальной необходимо соблюдать уникальность IP-адресов, а на каждом компьютере — и номеров портов, через которые устанавливаются соединения.

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

Цель лабораторных работ

Получить навыки работы с приложениями для создания виртуальных машин (ВМ) на примере Oracle Virtual Box 4.1.6 и выше на базе реального компьютера, научиться устанавливать операционные системы сервера и рабочей станции и связывать виртуальные компьютеры в сеть, осуществлять экспорт и импорт виртуальной машины.

Задания

1. Установить на ПК Oracle Virtual Box 4.1.6.

2. Создать виртуальную машину – рабочую станцию, установить на нее операционную систему (Windows XP или Windows 7).

3. Создать виртуальную машину – сервер, установить на нее операционную систему (Windows Server 2003 или 2008).

4. Создать вторую ВМ — рабочую станцию путем экспорта первой и импорта с новым именем. Удалите вторую ВМ.

5. Связать в виртуальную сеть ВМ – рабочую станцию и ВМ – сервер.

Средства для выполнения работы:

аппаратные: ПК с установленной ОС Windows (XP или 7);

программные: приложение Oracle Virtual Box 4.1.6, установочные образы ОС (сервера и рабочей станции).

ХОД ВЫПОЛНЕНИЯ РАБОТЫ

ЗАДАНИЕ №1. Установка Virtual Box

Запустите установочный файл Virtual Box и следуйте подсказкам Мастера Установки. После завершения установки запустите Virtual Box. Перед Вами главное окно программы.

Рис. 1. Главное окно Virtual Box
11

Выберите пункт «Свойства», а затем в меню слева выберите пункт «Ввод» и укажите хост-клавишу (например, Ctrl, по — умолчанию правый Ctrl). После этого нажмите на кнопку «ОК».

Рис. 2. Настройка хост — клавиши

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

2.2. ЗАДАНИЕ №2. Создание виртуальных машин:
рабочей станции и сервера

1. Для создания новой ВМ: кнопка «Создать»

Рис. 3. Главное окно Virtual Box

2. Появится Мастер создания новой ВМ. Следуйте инструкции мастера.

3. Далее необходимо выбрать семейство операционных систем, например, Microsoft Windows и версию Операционной Системы, например, Windows XP, и указать имя ВМ (например, myxp).

Рис. 4. Настройка параметров новой ВМ

4. Необходимо задать количество основной памяти, выделяемой ВМ, по умолчанию указывается рекомендуемый размер.

Рис. 5. Выбор размера основной памяти

5. Теперь необходимо создать виртуальный жёсткий диск. Т.к. это первая ВМ, и такого диска ещё нет, то создаем новый.

Рис. 6. Создание виртуального жесткого диска

6. Появится мастер создания нового виртуального жёсткого

диска, выберите тип файла VDI.

7. Затемосуществляется выбор дополнительных атрибутов создания диска: выбрать Динамический виртуальный диск.

— Расположение – то место, где будет храниться виртуальный жесткий диск на компьютере, размер выберите 10 ГБ.

Рис.7. Выбор расположения и размера нового диска

8. Далее отобразится сводная информация о создании виртуального жесткого диска.

Рис. 8. Сводная информация о диске

9. Подтвердите создание ВМ -.кнопка «Create»(создать).

Рис.9. Сводная информация о виртуальной машине

9. В результате отобразится список ВМ, для конфигурирования ВМ выберите её в списке слева, и нажмите кнопку «Свойства».

Рис. 10. Главное окно программы Virtual Box

  1. Выберите пункт «Система»/вкладка Материнская плата

Рис. 11. Пункт «Система»

Здесь можно изменить объем оперативной памяти, который выделяется ВМ, изменить порядок загрузки виртуальных устройств, включить или отключить опцию IO-APIC (нужна, если планируется использовать для виртуальной машины несколько ядер процессора), а также включить или отключить EFI (нужна для некоторых ОС, например MacOS). Выполните настройки, как на рисунке (Рис. 11).

  1. Переходим к вкладке «Процессор».

Рис. 12. Вкладка «Процессор»

Здесь можно указать, сколько ядер процессора может использовать виртуальная машина, а также включить или отключить PAE/NX (некоторые операционные системы поддерживают PAE, этот режим позволяет 32-битной виртуальной системе использовать до 64 Гб ОП). Выполните настройки, как на рисунке (Рис. 12).

13. Переходим к пункту «Дисплей».

Рис. 13. Пункт «Дисплей»

Virtual Box поддерживает 2D и 3D-ускорение (OpenGL / DirectX8 / DirectX9). Включите его. Выполните настройки, как на Рис 13.

14. Переходим к пункту «Сеть».

Рис. 14. Пункт «Сеть»

При установке VirtualBox в системе появилась еще одна сетевая карта, которая виртуально подключена к сетевой карте нашей виртуальной машины. Настраиваем виртуальный сетевой адаптер, как показано на рисунке выше (Рис. 14)

15. Перейдите на вкладку «Адаптер 2», подключите второй сетевой адаптер и выполните его настройку, как на рисунке (Рис. 15).

Рис. 15. Вкладка «Адаптер 2»

16. Перейдите к пункту «USB».

Рис. 16. Пункт «USB»

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

Затем на Windows виртуальной машины устанавливаются драйверы на новое USB устройство, и оно полноценно работает под управлением Windows. Основная система устройство видеть не будет.

Поскольку USB-устройств в системе много, то для того, чтобы при включении ВМ все они не отключались от основной и не подключались к виртуальной, была придумана система фильтров.

Фильтры указывают, какие USB-устройства должны отключаться от основной операционной системы и подключаться к Windows на виртуальной машине при ее включении.

Для добавления нового фильтра нажимаем на иконку с плюсиком и выбираем в списке необходимое USB-устройство.

Рис. 17. Выбор USB-устройста

После этого оно появляется в списке.

Рис. 18. Новое устройство в списке

17. Переходим к пункту «Общие папки».

Рис. 19. Пункт «Общие папки»

Для предоставления возможности работы с файлами на основной машине, надо организовать общий доступ к определенным папкам на винчестере. Для этого щелкаем мышкой на значке с плюсиком и выбираем папку на винчестере вашего компьютера, с которой будет работать Windows на ВМ. Вводим ее название и нажимаем «ОК».

Рис.20. Выбор пути к общей папке

Рис. 21. Выбор папки

Рис. 22. Добавление общей папки

18. После выполнения описанных выше действий общая папка появится в списке:

Рис. 23. Пункт «Общие папки»

19. Переходим в пункт «Носители», здесь необходимо добавить образ диска с операционной системой в виртуальный оптический привод, как показано на рисунках (24,25,26,27)

Рис. 24.

Рис. 25.

Рис. 26.

Рис. 27

20. После того как образ диска добавлен, можно приступать к установке ОС. Для этого выбрать только что созданную виртуальную ОС и нажать кнопку «Старт» как показано на рисунке 31.

Рис. 28

ЗАДАНИЕ №3. Установка операционных систем

Установка ОС Windows XP

21. Далее запускается стандартное окно установки Windows XP,

где в открывшемся меню необходимо выбрать пункт «Обычная установка Windows XP», нажать Enter, для того чтобы приступить к установке Windows XP.

Рис. 29.

24. В следующем окне выбрать необходимый раздел, куда будет установлена ОС. В данном случае мы имеем один раздел, поэтому просто нажать Enter.

25. Далее отформатировать выбранный раздел, в этом меню выбираем пункт меню «Форматировать в системе NTFS(быстрое)».

26. После завершения основного этапа установки откроется графическое окно настроек устанавливаемой ОС. В окне «Язык и региональные стандарты» жмем кнопку Далее.

Рис. 30

27. В окне «Настройка принадлежности программ» необходимо заполнить поля «Имя» и «Организация».

Рис. 31

28. В следующем окне необходимо ввести ключ продукта.

Рис. 32

29. Далее ввести имя компьютера и, при необходимости, пароль администратора.

Рис. 33
25

30. В следующем окне предлагается выбрать сетевые параметры устанавливаемой системы: выбрать пункт «обычные параметры» и нажать «Далее» (см. рис. 34).

Рис. 34.

31.Затем откроется окно «Пользователи компьютера», где предлагается ввести пользователей которые будут иметь доступ к данной ОС.

Рис. 35.

32. После всех проделанных операций отрывается рабочий стол только что установленной ОС Windows XP.

Примечание: поскольку клавиатура и мышка в ПК зачастую одна, то основная операционная система и операционная система, которая запущена на ВМ, вынуждены как-то ее делить.

Для этого используется механизм захвата. Иными словами, если на переднем плане виртуальная машина, то все, что вводится с клавиатуры, будет адресовано ей. Можно переключать и вручную. Для этого по умолчанию используется клавиша Host(см. раздел 2.1). Когда ВМ работает с клавиатурой и мышкой, то горит зеленая стрелочка в нижнем правом углу окна с ВМ.
26

Статьи к прочтению:

  • Основные команды операционной системы ms- dos
  • Основные команды при работе с архиваторами

Исследование функции. Найти основные свойства функции

Похожие статьи:

  • Основные характеристики и классификация компьютерных сетей

    ЛОКАЛЬНЫЕ И ГЛОБАЛЬНЫЕ СЕТИ. ОСНОВНЫЕ ПОНЯТИЯ. Содержание лекции: 1. Локальные и глобальные сети. Основные понятия. Сетевые и распределенные ОС. 2….

  • Windows 7 ее основные функции

    КОНТРОЛЬНАЯ РАБОТА по дисциплине «ИНФОРМАТИКА» Выполнил(а): студент(ка) _1____ курса инженерного факультета заочного отделения по направлению подготовки…

Виртуальная машина

Виртуальная машина Java

Designer Sun Microsystems
Биты 32- бит
Представлен 1994
Версия 14.0.1
Тип Стек и регистр – регистр
Кодирование Переменная
Ветвление Сравнение и ветвление
Порядок байтов Большой
Открыть Да
Регистры
Общее назначение Стек операндов для каждого метода (до 65535 операндов) плюс локальные переменные для каждого метода (до 65535)

Обзор архитектуры виртуальной машины Java (JVM) на основе спецификации виртуальной машины Java Java SE 7 Edition

A Виртуальная машина Java (JVM ) — это виртуальная машина, которая позволяет компьютеру запускать программы Java, а также программы, написанные на других языках, которые также скомпилированы в Байт-код Java. JVM подробно описывается в спецификации , которая формально описывает, что требуется в реализации JVM. Наличие спецификации обеспечивает возможность взаимодействия программ Java в различных реализациях, так что авторам программ, использующим Java Development Kit (JDK), не нужно беспокоиться об особенностях базовой аппаратной платформы.

Эталонная реализация JVM разработана проектом OpenJDK как код с открытым исходным кодом и включает JIT-компилятор, вызываемый HotSpot. Коммерчески поддерживаемые выпуски Java, доступные от Oracle Corporation, основаны на среде выполнения OpenJDK. Eclipse OpenJ9 — еще одна JVM с открытым исходным кодом для OpenJDK.

Содержание

  • 1 Спецификация JVM
    • 1.1 Загрузчик классов
    • 1.2 Архитектура виртуальной машины
    • 1.3 Инструкции байт-кода
    • 1.4 Языки JVM
    • 1.5 Средство проверки байт-кода
      • 1.5.1 Безопасное выполнение удаленный код
    • 1.6 Интерпретатор байт-кода и своевременный компилятор
  • 2 JVM в веб-браузере
    • 2.1 JavaScript JVM и интерпретаторы
    • 2.2 Компиляция в JavaScript
  • 3 Среда выполнения Java
    • 3.1 Производительность
    • 3.2 Куча поколений
    • 3.3 Безопасность
  • 4 См. Также
  • 5 Ссылки
  • 6 Внешние ссылки

Спецификация JVM

Виртуальная машина Java является абстрактной (виртуальной) компьютер определяется спецификацией. Используемый алгоритм сборки мусора и какая-либо внутренняя оптимизация инструкций виртуальной машины Java (их перевод в машинный код) не указаны. Основная причина этого упущения — не ограничивать разработчиков без необходимости. Любое приложение Java может быть запущено только внутри некоторой конкретной реализации абстрактной спецификации виртуальной машины Java.

Начиная с Java Platform, Standard Edition (J2SE) 5.0, изменения в спецификации JVM были разработаны в рамках процесса Java Community Process как JSR 924. Начиная с 2006 года, изменения в спецификации для поддержки изменений, предложенных для формата файла класса (JSR 202), выполняются в качестве обслуживания выпуск JSR 924. Спецификация JVM была опубликована в виде синей книги. В предисловии говорится:

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

Одна из JVM Oracle называется HotSpot, другая, унаследованная от BEA Systems, — Дж. Рокит. Чистая комната Реализации Java включают Kaffe, OpenJ9 и CEE-J Скельмира. Oracle владеет товарным знаком Java и может разрешить его использование для сертификации комплектов реализации как полностью совместимых со спецификацией Oracle.

Загрузчик классов

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

Загрузчик классов выполняет три основных действия в этом строгом порядке:

  1. Загрузка: находит и импортирует двоичные данные для типа
  2. Связывание: выполняет проверку, подготовку и (необязательно) разрешение
    • Проверка: обеспечивает правильность импортированного типа
    • Подготовка: выделяет память для переменных класса и инициализирует память значениями по умолчанию
    • Решение: преобразует символические ссылки из типа в прямые ссылки.
  3. Инициализация: вызывает Java-код, который инициализирует переменные класса их надлежащими начальными значениями.

В общем, существует два типа загрузчика классов: загрузчик классов начальной загрузки и пользовательский загрузчик классов.

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

Архитектура виртуальной машины

JVM оперирует примитивными значениями (целыми числами и числами с плавающей запятой) и ссылками. По сути, JVM — это 32-битная машина. Типы longи double, которые являются 64-битными, поддерживаются изначально, но используют две единицы памяти в локальных переменных кадра или стеке операндов, поскольку каждая единица имеет размер 32 бита. Все типы boolean, byte, shortи charотносятся к расширенному знаку (кроме char, который является расширенным нулем ) и работает как 32-битные целые числа, то же самое, что и типы int. У меньших типов есть только несколько инструкций по загрузке, сохранению и преобразованию типов. booleanобрабатывается как 8-битные байтовыезначения, где 0 представляет false, а 1 представляет true. (Хотя логическоерассматривалось как тип, так как Спецификация виртуальной машины Java, Второе издание разъяснила эту проблему, в скомпилированном и исполняемом коде есть небольшая разница между логическим и байт, за исключением изменения имени в сигнатурах методов и типа логических массивов. логическиев сигнатурах методов искажаются как Zв то время как байтыизменяются как B. Логические массивы несут тип boolean, но используют 8 бит на элемент, а JVM не имеет встроенных возможностей для упаковки логических значений в битовый массив, поэтому, за исключением типа, который они выполняют и ведут себя так же, как массивы byte. Во всех других случаях используется тип booleanфактически неизвестно JVM, поскольку все инструкции для работы с логическими значениями также используются для работы с байтамиs.)

JVM имеет кучу со сборкой мусора для хранения объекты и массивы. Код, константы и другие данные класса хранятся в «области метода». Область метода логически является частью кучи, но реализации могут обрабатывать область метода отдельно от кучи и, например, не могут собирать ее мусором. Каждый поток JVM также имеет свой собственный стек вызовов (для ясности называемый «стеком виртуальной машины Java»), в котором хранятся кадры. Новый фрейм создается каждый раз, когда вызывается метод, и фрейм уничтожается при выходе из этого метода.

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

инструкциями байт-кода

JVM имеет инструкций для следующих групп задач:

Целью является двоичная совместимость. Каждому конкретному хосту операционной системе требуется собственная реализация JVM и среды выполнения. Эти JVM интерпретируют байт-код семантически одинаково, но фактическая реализация может отличаться. Более сложным, чем просто эмуляция байт-кода, является совместимая и эффективная реализация API ядра Java, который должен быть сопоставлен с каждой операционной системой хоста.

Эти инструкции работают с набором общих абстрактных типов данных, а не с собственными типами данных любой конкретной архитектуры набора команд.

языков JVM

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

Существует несколько языков JVM, как старые языки, перенесенные на JVM, так и совершенно новые языки. JRuby и Jython, пожалуй, самые известные порты существующих языков, то есть Ruby и Python соответственно. Из новых языков, которые были созданы с нуля для компиляции в байт-код Java, Clojure, Apache Groovy, Scala и Kotlin могут быть самые популярные. Примечательной особенностью языков JVM является то, что они совместимы друг с другом, так что, например, библиотеки Scala могут использоваться с программами Java и наоборот.

Java 7 JVM реализует JSR 292: Поддержка динамически типизированных языков на платформе Java, новая функция, которая поддерживает динамически типизированные языки в JVM. Эта функция разработана в рамках проекта Da Vinci Machine, задача которого — расширить JVM таким образом, чтобы она поддерживала языки, отличные от Java.

Средство проверки байт-кода

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

JVM проверяет весь байт-код перед его выполнением. Эта проверка состоит в основном из трех типов проверок:

  • Ветви всегда ведут в допустимые места
  • Данные всегда инициализируются, а ссылки всегда безопасны для типов
  • Доступ к частным или пакетным частным данным и методы жестко контролируются

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

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

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

Безопасное выполнение удаленного кода

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

Формальное подтверждение верификаторов байт-кода было сделано в индустрии Javacard (формальная разработка встроенного верификатора для байт-кода карты Java)

Интерпретатор байт-кода и своевременный компилятор

Для каждой аппаратной архитектуры требуется свой интерпретатор байт-кода Java . Когда компьютер имеет интерпретатор байт-кода Java, он может запускать любую программу байт-кода Java, и ту же программу можно запускать на любом компьютере, на котором есть такой интерпретатор.

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

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

Байт-код Java не зависит от платформы и безопасен. Некоторые реализации JVM не включают интерпретатор, а состоят только из оперативного компилятора.

JVM в веб-браузере

В начале жизненного цикла платформы Java JVM была продается как веб-технология для создания многофункциональных Интернет-приложений. По состоянию на 2018 г. большинство веб-браузеров и операционных систем, объединяющих веб-браузеры, не поставляются с подключаемым модулем Java и не разрешают боковую загрузку любых файлов, отличных от Flash плагин. Подключаемый модуль браузера Java устарел в JDK 9.

Подключаемый модуль браузера Java NPAPI был разработан, чтобы позволить JVM выполнять так называемые апплеты Java, встроенные в страницы HTML.. Для браузеров с установленным подключаемым модулем апплету разрешено рисовать в прямоугольной области на странице, назначенной ему. Поскольку подключаемый модуль включает JVM, апплеты Java не ограничиваются языком программирования Java; любой язык, предназначенный для JVM, может работать в подключаемом модуле. Ограниченный набор API-интерфейсов позволяет апплетам получать доступ к микрофону пользователя или к 3D-ускорению, хотя апплеты не могут изменять страницу за пределами ее прямоугольной области. Adobe Flash Player, основная конкурирующая технология, работает в этом отношении точно так же.

По данным W3Techs, по состоянию на июнь 2015 года использование Java-апплетов и Silverlight для всех веб-сайтов упало до 0,1% каждый, а Flash — до 10,8%.

JVM и интерпретаторы JavaScript

По состоянию на май 2016 года JavaPoly позволяет пользователям импортировать немодифицированные библиотеки Java и вызывать их непосредственно из JavaScript. JavaPoly позволяет веб-сайтам использовать немодифицированные библиотеки Java, даже если на компьютере пользователя не установлена ​​Java.

Компиляция в JavaScript

С постоянным улучшением скорости выполнения JavaScript в сочетании с увеличением при использовании мобильных устройств, веб-браузеры которых не поддерживают плагины, предпринимаются попытки нацелить на этих пользователей компиляцию в JavaScript. Можно скомпилировать исходный код или байт-код JVM в JavaScript.

Компиляция байт-кода JVM, который является универсальным для языков JVM, позволяет создавать байт-код на основе существующего компилятора языка. Основным байт-кодом JVM для компиляторов JavaScript являются TeaVM, компилятор, содержащийся в Dragome Web SDK, Bck2Brwsr и j2js-compiler.

Ведущие компиляторы с языков JVM на JavaScript включают компилятор Java-to-JavaScript, содержащийся в Google Web Toolkit, Clojurescript (Clojure ), GrooScript (Apache Groovy ), Scala.js (Scala) и другие.

Среда выполнения Java

Среда выполнения Java (JRE), выпущенная Oracle, представляет собой свободно доступный дистрибутив программного обеспечения, содержащий автономную JVM (HotSpot ), стандартную библиотеку Java (Библиотека классов Java ), инструмент настройки и — до его прекращения в JDK 9 — подключаемый модуль браузера. Это наиболее распространенная среда Java, устанавливаемая на персональных компьютерах портативных и настольных ПК форм-фактора. Мобильные телефоны, включая телефоны с функциями и первые смартфоны, которые поставляются с JVM, скорее всего, будут включать JVM, предназначенную для запуска приложений, ориентированных на Micro Edition платформы Java. Между тем, большинство современных смартфонов, планшетных компьютеров и других портативных ПК, на которых запущены приложения Java, скорее всего, будут делать это благодаря поддержке операционной системы Android, которая включает виртуальную машину с открытым исходным кодом, несовместимую со спецификацией JVM. (Вместо этого инструменты разработки Google для Android принимают программы Java в качестве ввода и вывода байт-код Dalvik, который является собственным форматом ввода для виртуальной машины на устройствах Android.)

Производительность

Спецификация JVM дает разработчикам большую свободу действий в отношении деталей реализации. Начиная с Java 1.3, JRE от Oracle содержит JVM под названием HotSpot. Он был разработан как высокопроизводительная JVM.

Чтобы ускорить выполнение кода, HotSpot полагается на своевременную компиляцию. Чтобы ускорить выделение объектов и сборку мусора, HotSpot использует кучу поколений.

Куча поколений

Куча виртуальной машины Java — это область памяти, используемая JVM для распределения динамической памяти.

В HotSpot куча разделяется на поколения:

  • Молодое поколение хранит недолговечные объекты, которые создаются, и немедленно собирает мусор.
  • . Объекты, которые сохраняются дольше, перемещаются в старое поколение (также называемое постоянным поколением). Эта память подразделяется на (два) пространства выживших, где хранятся объекты, которые пережили первую и следующую сборку мусора.

Постоянное поколение (или перманент) использовалось для определений класса и связанных метаданных до Java 8. Постоянное поколение не было частью кучи. Постоянная генерация была удалена из Java 8.

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

Безопасность

Oracle JRE установлена ​​на большом количестве компьютеров. Таким образом, конечные пользователи с устаревшей версией JRE уязвимы для многих известных атак. Это привело к широко распространенному мнению, что Java по своей сути небезопасна. Начиная с Java 1.7, Oracle JRE для Windows включает функцию автоматического обновления.

До прекращения поддержки подключаемого модуля Java-браузера на любой веб-странице потенциально мог быть запущен Java-апплет, который обеспечивал легкодоступную поверхность атаки для вредоносных веб-сайтов. В 2013 году «Лаборатория Касперского» сообщила, что компьютерные злоумышленники предпочитают плагин Java. Эксплойты Java включены во многие пакеты эксплойтов, которые хакеры размещают на взломанных веб-сайтах. Аплеты Java были удалены из Java 11, выпущенного 25 сентября 2018 г.

См. Также

  • icon Портал компьютерного программирования

Ссылки

Внешние ссылки

Выполнение программы
Общие понятия
  • Код
  • Перевод
    • Компилятор
      • Время компиляции
    • Оптимизирующий компилятор
  • Промежуточное представительство (ИК)
  • Исполнение
    • Система выполнения
      • Время выполнения
    • Исполняемый
    • Устный переводчик
    • Виртуальная машина
Типы кода
  • Исходный код
  • Код объекта
  • Байт-код
  • Машинный код
  • Микрокод
Стратегии компиляции
  • Вовремя (JIT)
    • Отслеживание точно в срок
  • Раньше времени (AOT)
  • Транскомпиляция
  • Перекомпиляция
Заметное время выполнения
  • Android Runtime (ИЗОБРАЗИТЕЛЬНОЕ ИСКУССТВО)
  • общеязыковая среда выполнения (CLR) & Мононуклеоз
  • crt0
  • HHVM
  • Виртуальная машина Java (JVM)
  • Цель-C
  • V8
    • Node.js
  • PyPy
  • Zend Engine
Известные компиляторы и инструментальные средства
  • Коллекция компиляторов GNU (GCC)
  • LLVM
    • Лязг

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

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

  • Системные виртуальные машины (также называемый полная виртуализация ВМ) обеспечивают замену реальной машине. Они обеспечивают функциональность, необходимую для выполнения всего операционные системы. А гипервизор использует родное исполнение для совместного использования оборудования и управления им, что позволяет использовать несколько сред, которые изолированы друг от друга, но существуют на одной физической машине. Современные гипервизоры используют виртуализация с аппаратной поддержкой, аппаратное обеспечение для виртуализации, в основном из центральных процессоров.
  • Виртуальные машины процессов предназначены для выполнения компьютерных программ в платформо-независимой среде.

Некоторые виртуальные машины, например QEMU, разработаны для имитации различных архитектур и позволяют выполнять программные приложения и операционные системы, написанные для другого ЦПУ или архитектура. Виртуализация на уровне операционной системы позволяет разделить ресурсы компьютера через ядро. Термины не являются взаимозаменяемыми.

Определения

Системные виртуальные машины

«Виртуальная машина» изначально была определена Попек и Гольдберг как «эффективный изолированный дубликат реальной компьютерной машины».[1] Текущее использование включает виртуальные машины, которые не имеют прямого отношения к какому-либо реальному оборудованию.[2]Физическое, «реальное» оборудование, на котором работает виртуальная машина, обычно называется «хостом», а виртуальная машина, эмулируемая на этой машине, обычно называется «гостевой». Хост может эмулировать несколько гостей, каждый из которых может эмулировать различные операционные системы и аппаратные платформы.

Желание запускать несколько операционных систем было первоначальным мотивом для виртуальных машин, чтобы обеспечить разделение времени между несколькими однозадачными операционными системами. В некоторых отношениях системную виртуальную машину можно рассматривать как обобщение концепции виртуальная память что исторически предшествовало этому. IBM CP / CMS, первые системы, позволяющие полная виртуализация, реализовано совместное времяпровождение предоставляя каждому пользователю однопользовательскую операционную систему, Система разговорного монитора (CMS). В отличие от виртуальной памяти, системная виртуальная машина дает пользователю право писать привилегированные инструкции в своем коде. У этого подхода были определенные преимущества, такие как добавление устройств ввода / вывода, не разрешенных стандартной системой.[2]

По мере того, как технологии развивают виртуальную память для целей виртуализации, новые системы чрезмерное использование памяти может применяться для управления совместным использованием памяти несколькими виртуальными машинами в одной операционной системе компьютера. Возможно, можно будет поделиться страницы памяти которые имеют идентичное содержимое на нескольких виртуальных машинах, работающих на одной физической машине, что может привести к их сопоставлению с одной и той же физической страницей методом, называемым слияние одной страницы ядра (КСМ). Это особенно полезно для страниц, предназначенных только для чтения, таких как страницы, содержащие сегменты кода, что характерно для нескольких виртуальных машин, на которых запущено одно и то же или подобное программное обеспечение, программные библиотеки, веб-серверы, компоненты промежуточного программного обеспечения и т. Д. Гостевые операционные системы не нуждаются в быть совместимым с аппаратным обеспечением хоста, что позволяет запускать разные операционные системы на одном компьютере (например, Windows, Linux или предыдущие версии операционной системы) для поддержки будущего программного обеспечения.[3]

Использование виртуальных машин для поддержки отдельных гостевых операционных систем популярно в отношении встроенные системы. Типичное использование — запуск операционная система реального времени одновременно с предпочтительной сложной операционной системой, такой как Linux или Windows. Другое применение — новое и непроверенное программное обеспечение, все еще находящееся на стадии разработки, поэтому оно работает внутри песочница. Виртуальные машины имеют другие преимущества для разработки операционных систем и могут включать улучшенный доступ для отладки и более быструю перезагрузку.[4]

Для консолидации серверов часто используются несколько виртуальных машин с собственной гостевой операционной системой.[5]

Виртуальные машины процессов

«Виртуальная машина приложения» перенаправляется сюда. Не следует путать с виртуализация приложений.

ВМ процесса, иногда называемая виртуальная машина приложения, или же Управляемая среда выполнения (MRE), запускается как обычное приложение внутри ОС хоста и поддерживает один процесс. Он создается при запуске этого процесса и уничтожается при выходе. Его цель — предоставить Платформа -независимая среда программирования, которая абстрагирует детали базового оборудования или операционной системы и позволяет программе выполняться одинаково на любой платформе.

Виртуальная машина процесса обеспечивает абстракцию высокого уровня — абстракцию язык программирования высокого уровня (по сравнению с низкоуровневой абстракцией ISA системной виртуальной машины). Виртуальные машины процессов реализуются с использованием устный переводчик; производительность, сравнимая с компилируемыми языками программирования, может быть достигнута за счет использования своевременная компиляция.[нужна цитата ]

Этот тип ВМ стал популярен среди Язык программирования Java, который реализован с помощью Виртуальная машина Java. Другие примеры включают Виртуальная машина Parrot и .NET Framework, который работает на виртуальной машине, называемой общеязыковая среда выполнения. Все они могут служить слой абстракции для любого компьютерного языка.

Частным случаем виртуальных машин процесса являются системы, которые абстрагируются от механизмов связи (потенциально гетерогенных) компьютерный кластер. Такая виртуальная машина состоит не из одного процесса, а из одного процесса на физическую машину в кластере. Они предназначены для облегчения задачи программирования параллельных приложений, позволяя программисту сосредоточиться на алгоритмах, а не на механизмах связи, обеспечиваемых межсоединением и ОС. Они не скрывают того факта, что происходит обмен данными, и как таковые не пытаются представить кластер как единую машину.[нужна цитата ]

В отличие от других виртуальных машин процесса, эти системы не предоставляют определенный язык программирования, а встроены в существующий язык; обычно такая система предоставляет привязки для нескольких языков (например, C и Фортран ).[нужна цитата ] Примеры Параллельная виртуальная машина (PVM) и Интерфейс передачи сообщений (MPI). Они не являются строго виртуальными машинами, потому что приложения, работающие поверх, по-прежнему имеют доступ ко всем службам ОС и, следовательно, не ограничиваются системной моделью.

История

Эта секция нужны дополнительные цитаты для проверка. Пожалуйста помоги улучшить эту статью к добавление цитат в надежные источники. Материал, не полученный от источника, может быть оспорен и удален. (Июль 2015 г.) (Узнайте, как и когда удалить этот шаблон сообщения)

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

Системные виртуальные машины вырос из совместное времяпровождение, как это заметно реализовано в Совместимая система разделения времени (CTSS). Разделение времени позволило нескольким пользователям использовать компьютер одновременно: каждая программа имела полный доступ к машине, но одновременно выполнялась только одна программа, при этом система переключалась между программами во временных срезах, сохраняя и восстанавливая состояние каждый раз. Это превратилось в виртуальные машины, в частности с помощью исследовательских систем IBM: M44 / 44X, который использовал частичная виртуализация, а CP-40 и Симмон, который использовал полная виртуализация, и были ранними примерами гипервизоры. Первой широко доступной архитектурой виртуальных машин была CP-67 / CMS (см. История CP / CMS подробнее). Важное различие заключалось в использовании нескольких виртуальных машин в одной хост-системе для разделения времени, как в M44 / 44X и CP-40, и использовании одной виртуальной машины в хост-системе для прототипирования, как в SIMMON. Эмуляторы, с аппаратной эмуляцией более ранних систем для совместимости, восходящей к IBM System / 360 в 1963 г.,[6][7] в то время как программная эмуляция (так называемая «симуляция») предшествует ей.

Виртуальные машины процессов возникла первоначально как абстрактные платформы для промежуточный язык используется как промежуточное представление программы компилятор; ранние образцы датируются примерно 1966 годом. Примером начала 1966 года был О-код машина, виртуальная машина, которая выполняет О-код (объектный код), излучаемый внешний интерфейс из BCPL компилятор. Эта абстракция позволила легко перенести компилятор на новую архитектуру за счет реализации нового задний конец который взял существующий O-код и скомпилировал его в машинный код для базовой физической машины. В Эйлер язык использовал похожий дизайн, с промежуточным языком, названным п (переносной).[8] Это было популяризировано примерно в 1970 г. Паскаль, особенно в Паскаль-П система (1973) и Паскаль-S компилятор (1975), в котором он был назван p-код и получившаяся машина как машина p-кода. Это оказало влияние, и виртуальные машины в этом смысле часто назывались машинами с p-кодом. Помимо того, что он был промежуточным языком, p-код Pascal также выполнялся напрямую интерпретатором, реализующим виртуальную машину, особенно в UCSD Паскаль (1978); это повлияло на более поздних интерпретаторов, особенно на Виртуальная машина Java (JVM). Другой ранний пример был СНОБОЛ4 (1967), который был написан на языке реализации SNOBOL (SIL), ассемблере для виртуальной машины, который затем был нацелен на физические машины путем переноса на их родной ассемблер через макроассемблер.[9] Однако с тех пор макросы перестали быть популярными, поэтому такой подход оказался менее влиятельным. Виртуальные машины процессов были популярным подходом к внедрению раннего программного обеспечения микрокомпьютеров, включая Tiny BASIC и приключенческие игры, от разовых реализаций, таких как Пирамида 2000 к двигателю общего назначения, например Инфоком с z-машина, который Грэм Нельсон утверждает, что это «возможно, самая портативная виртуальная машина из когда-либо созданных».[10]

Значительный прогресс произошел во внедрении Болтовня -80,[11]особенно реализация Deutsch / Schiffmann[12]который толкнул своевременная (JIT) компиляция вперед как подход к реализации, использующий виртуальную машину процесса.[13]Позже известные виртуальные машины Smalltalk были VisualWorks, то Виртуальная машина Squeak,[14]и Strongtalk.[15]Родственным языком, который привел к появлению множества инноваций в виртуальных машинах, был Себя язык программирования,[16] который первым адаптивная оптимизация[17] и сборка мусора поколений. Эти методы оказались коммерчески успешными в 1999 г. HotSpot Виртуальная машина Java.[18]Другие нововведения включают наличие виртуальной машины на основе регистров для лучшего соответствия базовому оборудованию, а не виртуальной машины на основе стека, которая больше соответствует языку программирования; в 1995 году это было впервые сделано Виртуальная машина Dis для Лимбо язык. OpenJ9 является альтернативой HotSpot JVM в OpenJDK и представляет собой проект eclipse с открытым исходным кодом, требующий лучшего запуска и меньшего потребления ресурсов по сравнению с HotSpot.

Полная виртуализация

Логическая схема полной виртуализации

При полной виртуализации виртуальная машина имитирует достаточно оборудования, чтобы позволить немодифицированную «гостевую» ОС (предназначенную для той же Набор инструкций ) для изолированного выполнения. Этот подход был впервые применен в 1966 году с IBM CP-40 и CP-67, предшественники ВМ семья.

Примеры вне поля мэйнфрейма включают Parallels Workstation, Parallels Desktop для Mac, VirtualBox, Виртуальное железо, ВМ Oracle, Виртуальный ПК, Виртуальный сервер, Hyper-V, VMware Workstation, Сервер VMware (прекращено, ранее называлось GSX Server), VMware ESXi, QEMU, Adeos, Mac-на-Linux, Win4BSD, Win4Lin Pro, и Egenera Технология vBlade.

Аппаратная виртуализация

При аппаратной виртуализации аппаратное обеспечение обеспечивает архитектурную поддержку, которая облегчает создание монитора виртуальных машин и позволяет изолированно запускать гостевые ОС.[19]Аппаратная виртуализация была впервые представлена ​​в IBM System / 370 в 1972 году для использования с VM / 370, первая операционная система для виртуальных машин, предлагаемая IBM в качестве официального продукта.[20]

В 2005 и 2006 гг. Intel и AMD предоставил дополнительное оборудование для поддержки виртуализации. Sun Microsystems (сейчас Корпорация Oracle ) добавили аналогичные функции в свои UltraSPARC серии T процессоров в 2005 году. Примеры платформ виртуализации, адаптированных к такому оборудованию, включают KVM, VMware Workstation, VMware Fusion, Hyper-V, Виртуальный ПК с Windows, Xen, Parallels Desktop для Mac, Oracle VM Server для SPARC, VirtualBox и Parallels Workstation.

В 2006 году было обнаружено, что поддержка 32- и 64-разрядного оборудования x86 первого поколения редко дает преимущества в производительности по сравнению с программной виртуализацией.[21]

Виртуализация на уровне операционной системы

При виртуализации на уровне операционной системы физический сервер виртуализируется на уровне операционной системы, что позволяет нескольким изолированным и безопасным виртуализированным серверам работать на одном физическом сервере. «Гостевые» операционные среды используют тот же запущенный экземпляр операционной системы, что и хост-система. Таким образом, тот же ядро операционной системы также используется для реализации «гостевой» среды, и приложения, работающие в данной «гостевой» среде, рассматривают ее как автономную систему. Пионерская реализация была Тюрьмы FreeBSD; другие примеры включают Докер, Контейнеры Solaris, OpenVZ, Linux-VServer, LXC, AIX Разделы рабочей нагрузки, Parallels Virtuozzo Containers и Виртуальные учетные записи iCore.

Смотрите также

  • Образ машины Amazon
  • Контейнеры Linux
  • Родной комплект разработчика
  • Паравиртуализация
  • Гипервизор хранилища
  • Универсальная машина Тьюринга
  • Виртуальное устройство
  • Виртуальное устройство резервного копирования
  • Образ виртуального диска
  • Виртуальная машина DOS (VDM)
  • Побег на виртуальной машине

Рекомендации

  1. ^ Попек, Джеральд Дж.; Гольдберг, Роберт П. (1974). «Формальные требования к виртуализируемым архитектурам третьего поколения» (PDF). Коммуникации ACM. 17 (7): 412–421. Дои:10.1145/361011.361073. S2CID  12680060.
  2. ^ а б Смит, Джеймс Э .; Наир, Рави (2005). «Архитектура виртуальных машин». Компьютер. 38 (5): 32–38, 395–396. Дои:10.1109 / MC.2005.173. S2CID  6578280.
  3. ^ Олифант, Патрик. «Виртуальные машины». Виртуальные вычисления. Архивировано из оригинал в 2016-07-29. Получено 2015-09-23. Некоторые люди используют эту возможность для настройки отдельной виртуальной машины под управлением Windows на Mac, предоставляя им доступ ко всему спектру приложений, доступных для обеих платформ.
  4. ^ «Сверхбыстрая перезагрузка сервера — еще одна причина крушения виртуализации». vmwarez.com. 2006-05-09. Архивировано из оригинал на 2006-06-14. Получено 2013-06-14.
  5. ^ «Консолидация и локализация серверов с помощью виртуальной инфраструктуры» (PDF). VMware. 2007. В архиве (PDF) из оригинала 28.12.2013. Получено 2015-09-29.
  6. ^ Пью, Эмерсон В. (1995). Строительство IBM: формирование отрасли и ее технологий. Массачусетский технологический институт. п.274. ISBN  978-0-262-16147-3.
  7. ^ Пью, Эмерсон В.; и другие. (1991). Системы IBM 360 и Early 370. Массачусетский технологический институт. стр.160–161. ISBN  978-0-262-16123-7.
  8. ^ Вирт, Никлаус Эмиль; Вебер, Гельмут (1966). EULER: обобщение АЛГОЛА и его формальное определение: Часть II, Коммуникации Ассоциации вычислительной техники. 9. Нью-Йорк: ACM. С. 89–99.
  9. ^ Грисволд, Ральф Э. Макро-реализация SNOBOL4. Сан-Франциско, Калифорния: W. H. Freeman and Company, 1972 (ISBN  0-7167-0447-1), Глава 1.
  10. ^ Нельсон, Грэм А. «О переводчиках». Информ сайт. В архиве из оригинала от 03.12.2009. Получено 2009-11-07.
  11. ^ Гольдберг, Адель; Робсон, Дэвид (1983). Smalltalk-80: язык и его реализация. Серия Аддисона-Уэсли в области компьютерных наук. Эддисон-Уэсли. ISBN  978-0-201-11371-6.
  12. ^ Дойч, Л. Питер; Шиффман, Аллан М. (1984). «Эффективное внедрение системы Smalltalk-80». POPL. Солт-Лейк-Сити, Юта: ACM. Дои:10.1145/800017.800542. ISBN  0-89791-125-3.
  13. ^ Эйкок, Джон (2003). «Краткая история точно в срок». ACM Comput. Surv. 35 (2): 97–113. Дои:10.1145/857076.857077. S2CID  15345671.
  14. ^ Ингаллс-младший, Дэниел «Дэн» Генри Холмс; Kaehler, Тед; Мэлони, Джон; Уоллес, Скотт; Кей, Алан Кертис (1997). «Назад в будущее: история Squeak, практического языка Smalltalk, написанного сама по себе». OOPSLA ’97: Материалы 12-й конференции ACM SIGPLAN по объектно-ориентированному программированию, системам, языкам и приложениям. Нью-Йорк, Нью-Йорк, США: ACM Press. С. 318–326. Дои:10.1145/263698.263754. ISBN  0-89791-908-4.
  15. ^ Браха, Гилад; Грисволд, Дэвид (1993). «Strongtalk: Smalltalk для проверки типов в производственной среде». Труды восьмой ежегодной конференции по объектно-ориентированным программным системам, языкам и приложениям. ОПСЛА 93 года. Нью-Йорк, Нью-Йорк, США: ACM. С. 215–230. Дои:10.1145/165854.165893. ISBN  978-0-89791-587-8.
  16. ^ Ангар, Дэвид Майкл; Смит, Рэндалл Б. (декабрь 1987 г.). «Я: сила простоты». Уведомления ACM SIGPLAN. 22 (12): 227–242. Дои:10.1145/38807.38828. ISSN  0362-1340.
  17. ^ Hölzle, Urs; Ангар, Дэвид Майкл (1994). «Оптимизация динамически отправляемых вызовов с обратной связью во время выполнения». PLDI. Орландо, Флорида, США: ACM. С. 326–336. Дои:10.1145/178243.178478. ISBN  0-89791-662-X.
  18. ^ Палечны, Майкл; Вик, Кристофер; Щелкни, Клифф (2001). «Серверный компилятор Java HotSpot». Материалы симпозиума по исследованиям и технологиям виртуальных машин Java на Симпозиуме по исследованиям и технологиям виртуальных машин Java. 1. Монтерей, Калифорния: Ассоциация USENIX.
  19. ^
  20. ^ Рэндал, А. (2019). Идеальное против реального: возвращаясь к истории виртуальных машин и контейнеров.
  21. ^ Адамс, Кейт; Агесен, Оле (21 октября 2006 г.). Сравнение программных и аппаратных методов виртуализации x86 (PDF). ASPLOS’06 21–25 октября 2006 г. Сан-Хосе, Калифорния, США. В архиве (PDF) из оригинала 20.08.2010. К удивлению, мы обнаружили, что поддержка оборудования первого поколения редко дает преимущества в производительности по сравнению с существующими программными технологиями. Мы объясняем эту ситуацию высокими затратами на переход между VMM и гостевой системой и жесткой моделью программирования, которая оставляет мало места для гибкости программного обеспечения в управлении частотой или стоимостью этих переходов.

дальнейшее чтение

  • Джеймс Э. Смит, Рави Наир, Виртуальные машины: универсальные платформы для систем и процессов, Морган Кауфманн, май 2005 г., ISBN  1-55860-910-5, 656 страниц (охватывает как процессные, так и системные виртуальные машины)
  • Крейг, Иэн Д. Виртуальные машины. Springer, 2006, ISBN  1-85233-969-1, 269 страниц (охватывает только виртуальные машины процессов)

внешняя ссылка

  • Мендель Розенблюм (31 августа 2004 г.). «Реинкарнация виртуальных машин». Очередь ACM. Vol. 2 шт. 5.
  • Sandia National Laboratories использует 1 миллион ядер Linux в качестве виртуальных машин
  • Дизайн виртуальной машины Inferno Филом Винтерботтомом и Робом Пайком
  • Зачем использовать виртуальные машины? — Тайфун Дегер

#статьи

  • 27 янв 2022

  • 0

Иван Углянский рассказал, как устроена JVM, что с ней не так и зачем Python, Ruby и другие языки переезжают на виртуальную машину Java.

Иллюстрация: Mark Kingston / WikiMedia Commons / Colowgee для Skillbox Media

Антон Сёмин

Пишет об истории IT, разработке и советской кибернетике. Знает Python, JavaScript и немного C++, но предпочитает писать на русском.


об эксперте

JVM engineer. Работает в Excelsior@Huawei над виртуальными машинами Java, компиляторами и новыми языками программирования. Один из основателей и лидеров JUGNsk, член программного комитета SnowOne Conference.



Я занимаюсь JVM более 10 лет. Начинал в новосибирской компании Excelsior, которая разрабатывала свою реализацию виртуальной машины Java — Excelsior JET. Потом мы вошли в состав Huawei, но команда осталась прежней.

До появления Java, примерно 25 лет назад, многие приложения писали на С или С++. У этих языков есть проблема: разработчику приходится думать, на какой операционке и архитектуре процессора будет работать его код. Например, если он пишет программу под Linux, то, скорее всего, она не запустится на Windows или MacOS. Поэтому код приходилось пичкать директивами условной компиляции или писать отдельную версию для каждой операционки.

Самую сильную боль вызывали приложения с GUI — код графических компонентов для разных операционок был совершенно разным. Причина в том, что C и C++ довольно близки к железу, а значит, сишник должен учитывать архитектуру процессора и тип операционной системы. Понятно, что никакой кроссплатформенностью здесь и не пахнет.

Ещё в 1960-е годы у инженеров появилась идея: писать программы не для конкретного железа, а для абстрактного «исполнителя». Программы на Java как раз пишутся для такого исполнителя — виртуальной машины, или Java Virtual Machine (JVM). Java-разработчик не задумывается, на какой платформе будет запускаться его код. В то же время виртуальная машина не знает, что исполняет инструкции на Java, ведь она принимает и исполняет байт-код.

В этом и было «уникальное торговое предложение» Java: разработчики писали программу под Windows, а она запускалась на macOS почти без изменений. Сейчас это звучит вполне естественно, а 25 лет назад казалось настоящим чудом.

Кадр: документальный сериал «Древние пришельцы»

Кроссплатформенность в Java обеспечивается явным разделением уровней языка и реализации.

Языковой уровень. Разработчики пишут код на языке Java, синтаксис и семантика которого описаны в Java Language Specification. После этого специальным инструментом, который называется javac, исходный код компилируется в байт-код Java. При этом происходит проверка синтаксиса, и в случае его нарушения разработчик получает сообщение об ошибке от javac.

Что здесь важно:

  1. На этом этапе нет ничего платформенно-специфичного, весь код на языке Java (как и байт-код Java) универсален.
  2. Байт-код Java — это язык, предназначенный не для людей, а для машин. Обычному разработчику его читать не нужно.

Уровень реализации. Полученный байт-код Java передаётся на вход виртуальной машины Java. И вот как именно она будет его исполнять, описано уже в другой спецификации — Java Virtual Machine Specification. Со всеми особенностями конкретной операционной системы или архитектуры процессора тоже разбирается JVM, без влияния на исходный код на языке Java. Таким образом, происходит перенос ответственности: разработчики на Java о таких неприятных вещах больше не думают, им достаточно просто взять правильную JVM (например, для Linux x64). А все OS/arch-специфические нюансы решают разработчики JVM.

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

У разделения языка и его реализации есть замечательное следствие: разработчику не обязательно ограничиваться языком Java, ведь виртуальная машина понятия не имеет, откуда взяли байт-код, который пришёл к ней на вход, был ли это изначально Java-код или что-то другое. То есть программу можно писать на любом языке, который транслируется в байт-код. И таких языков — целое семейство: Kotlin, Clojure, Groovy и так далее. Например, программы на Kotlin компилируются с помощью kotlinc в class-файлы, а затем подаются на вход JVM.

Java Development Kit (JDK) — это комплект инструментов для разработки приложений на Java. В него входят несколько компонентов, которые позволяют разрабатывать и запускать приложения:

  • Javас. Это компилятор, который преобразует исходники Java в class-файлы или формат jar.
  • JVM. Виртуальная машина, которая исполняет байт-код.
  • Стандартная библиотека. Набор модулей, классов, объектов и функций, которые доступны в языке.
  • Документация. В ней содержится справочная информация об инструментах данной версии JDK.

Когда появляется новая версия языка, все эти компоненты обновляются.

В случае стандартной JVM (например, HotSpot) запуск Java-приложения выглядит так: сначала с помощью javac вы компилируете исходный код в class-файлы (или jar-файлы), и именно их вы можете поставлять в качестве приложения.

Чтобы приложение запустилось на хосте, там должна быть установлена виртуальная машина. Тогда пользователь пишет в командной строке: java -jar <имя вашего jar-файла> — и программа запускается.

С нашей виртуальной машиной сценарий запуска приложения был другой: мы заранее компилировали class-файлы в один исполняемый exe-файл. Поэтому он работал на компьютере пользователя без каких-либо предустановленных JVM. Но, по сути, JVM никуда не исчезла — просто все её части были слинкованы в один экзешник.

В спецификации Java Virtual Machine почти ничего не сказано о том, как именно её реализовывать — только что должно получиться на выходе. Например, вы не можете явно освободить память из под объекта, когда он вам уже не нужен. Этим занимается специальный компонент JVM — Garbage Collector. Но вот как именно он работает, в спецификации не сказано.

Так и было задумано: спецификация позволяет создавать разные JVM, реализации которых в чём-то отличаются, но при этом удовлетворяют требованиям спецификации. И это замечательно, пусть расцветают сто цветов! Такие различия в реализации дают разным виртуальным машинам особые конкурентные преимущества: у кого-то более крутой сборщик мусора, у кого-то быстрый стартап, а кто-то реализовал более мощные оптимизации в компиляторе.

Первую JVM, как и язык Java, разработали в компании Sun Microsystems. Когда Sun опубликовала спецификацию, Oracle стала работать над своей JRockit, а IBM — над OpenJ9. Наша Excelsior JET вышла в свет в 2000 году.

Изначально все JVM были закрытыми, но в 2006 году Sun опубликовала исходники своей JVM HotSpot и компилятора javac, а потом и стандартной библиотеки Java. Это дало старт проекту OpenJDK — полностью открытой реализации JDK. Через какое-то время Sun была поглощена корпорацией Oracle, но при этом проект OpenJDK никуда не делся и до сих пор остаётся главной open-source-площадкой для разработки Java и JVM.

OpenJDK — это эталонная реализация, на которую ориентируются разработчики других виртуальных машин. Проект распространяется под GPL 2 + Classpath Exception, благодаря чему любая компания или разработчик, которым хватит квалификации, смогут форкнуть OpenJDK и начать разрабатывать свою собственную JVM. Конечно же, по условию лицензии их реализация тоже будет open source.

Существуют и реализации JVM, которые никак не связаны с OpenJDK. Ведь не только Sun Microsystems и Oracle создавали JVM. Другой пример — это IBM J9, которая, кстати, тоже открыла исходный код и стала называться OpenJ9.

Некоторые компании продают свои виртуальные машины. Например, у Azul есть свободная сборка Zulu и закрытая коммерческая Azul Zing. В последней есть уникальный сборщик мусора C4, который гарантировал низкие паузы ещё до того, как это стало мейнстримом. А также технология ReadyNow!, которая позволяет «запомнить» список всех оптимизаций кода и «проиграть» его на старте JVM, выводя машину на пиковую производительность.

Excelsior JET тоже была закрытой и платной. Она обеспечивала быстрый стартап, низкое потребление памяти и хорошую пиковую производительность во многих сценариях. Всё это мы получали за счёт статической компиляции, в отличие от динамической компиляции на лету в HotSpot.

Однако сегодня люди чаще пользуются бесплатными сборками, основанными на OpenJDK. Существуют как стандартные сборки OpenJDK от Oracle, так и сборки от других компаний и разработчиков, имеющих отношение к разработке OpenJDK (зачастую их публикуют контрибьюторы в OpenJDK не из Oracle).

В таких сборках могут быть дополнительные фичи, не включённые по умолчанию в стандартные сборки от Oracle. Либо такие альтернативные сборки прошли дополнительную сертификацию, например для использования с «КриптоПро». При этом такие сторонние билды проходят все стандартные тесты, поэтому гарантируется, что ваши программы будут работать как надо и пользоваться ими можно абсолютно безопасно и бесплатно.

Некоторые компании не только выкладывают свои билды, но и оказывают платную поддержку пользователям. Допустим, возникла проблема с виртуальной машиной: ваше приложение работает неожиданно медленно или даже крашится! Всякое бывает, ведь JVM — это тоже программа, в которой могут быть свои баги. Тогда инженеры этой компании оперативно разберутся в проблеме и решат её.

В целом вариантов виртуальных машин и их сборок очень много — в рамках этой статьи все не перечислить. Есть сборки от Oracle, Red Hat, Azul, IBM, BellSoft, Amazon и Microsoft. Сообщество Java-чемпионов написало замечательный документ, в котором перечислило все варианты и в целом разъяснило ситуацию с многообразием JVM и их сборок. Документ называется Java Is Still Free, рекомендую его всем к прочтению.

Java — это не просто язык, а целая философия. И она оказалась настолько востребованной, что у других языков программирования стали появляться реализации под JVM. Например, Jython и JRuby.

Главная причина появления таких реализаций — перформанс. За 25 лет человечество научилось делать хорошо оптимизированные JVM. Так почему бы за счёт этого не повысить производительность программ на Python и Ruby?

С другой стороны, так можно получить хорошую связь с экосистемой Java. Если мы запускаем код на JVM, он лучше взаимодействует с другими модулями на JVM. Значит, можно пользоваться и Java-библиотеками.

У Kotlin немного другая история. Когда язык только появился, было решено компилировать его в байт-код Java и запускать на JVM. Таким образом, реализация языка заключалась в написании хорошего транслятора — kotlinc — из исходного кода .kt в class-файлы. А реализация низкоуровневых компонентов типа сборщиков мусора или взаимодействия с операционной системой делегировалась уже существующим JVM.

Относительно недавно создатели Kotlin сделали Kotlin Native — технологию компиляции Kotlin в нативный код напрямую, без JVM. В нём низкоуровневые компоненты, такие как менеджер памяти, уже реализованы самостоятельно.

Хотя на словах кажется, что любой язык программирования легко перевести на JVM (достаточно написать транслятор в class-файлы), на деле всё оказывается намного сложнее. Грамотно отобразить фичи языка в байт-код Java и при этом получить хорошую производительность — нетривиальная задача. Посмотрите хотя бы на JRuby.

Чарльз Наттер часто делится опытом поддержки различных фич Ruby в проекте JRuby и рассказывает о сложностях, с которыми сталкивается. Чем дальше исходный язык от Java, тем сложнее задача трансляции. Но, думаю, всё возможно, и JRuby — наглядный тому пример.

Самый известный конкурент Java Virtual Machine — платформа .NET и их виртуальная машина для реализации C#.

В начале 2000-х Microsoft делала свою виртуальную машину Java — Microsoft J++. Но из-за того, что корпорация не соблюдала спецификацию, Sun подала на неё судебный иск. Microsoft проиграла все суды и лишилась права делать виртуальную машину для Java. Есть мнение, что это стало одной из причин появления C#.

Java и C# решают одни и те же задачи и обладают одними и теми же преимуществами: строгая типизация, сборка мусора, безопасность — всё это совпадает. Это managed-языки широкого применения.

Раньше между платформами была одна принципиальная разница: Java был кроссплатформенным, а .NET и C# работали только на Windows. Но с тех пор, как появился .NET Core, C# тоже стал мультиплатформенным.

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

Зато у Java мощная реализация и хорошо оптимизированные виртуальные машины. Это стало возможным благодаря «гонке вооружений» между разработчиками виртуальных машин. Вендоры на протяжении 20 лет соревновались, кто сделает самую крутую оптимизацию, лучший алгоритм сборки мусора, более быстрый стартап и так далее. Поэтому по многим показателям реализация Java выглядит куда лучше C#. Некоторые вещи, которые уже давно есть в JVM, только-только появляются в .NET.

Есть и другие языки, которые претендуют на роль конкурента Java, но они отличаются гораздо сильнее. Например, Python, который недавно занял 1-е место в рейтинге TIOBE. Он популярен в Data Science, AI, машинном обучении, скриптах и так далее. К сожалению, динамическая типизация не позволяет держать на нём слишком большую кодовую базу.

Ещё есть безумно популярный JavaScript, но его интересы с Java не очень пересекаются, так как сегодня Java во фронтенде не используется. Хотя когда-то были и такие планы (привет устаревшей технологии Java-апплетов).

Java широко используют в бэкенде, то есть во всех приложениях, которые работают на стороне сервера. Его главный конкурент — C#, но Java всё-таки значительно лидирует, потому что считается более кроссплатформенным. Хотя последнее уже не совсем правда. Также стоит отметить, что у Java банально есть фора по времени по сравнению с C#. Он появился на 10 лет раньше, поэтому успел захватить умы разработчиков и кодовые базы.

Почему Java, а не «швейцарский нож» С++? Просто Java удобнее и безопаснее для жизни, или, как принято говорить, не даст выстрелить себе в ногу. Разработчику не нужно думать об управлении памятью и сегфолтах, которые могу прилететь хоть откуда. Поэтому, когда дело касается будничных задач бэкенда, скорость разработки на Java и C# гораздо выше, чем на C++.

Java плохо подходит для приложений, которым требуется высокая производительность и гарантированное время отклика. Тем не менее некоторые пишут на Java и такие программы, если готовы мириться с небольшими задержками в микросекунды. Для них выигрыш от скорости разработки и надёжности важнее. Но писать на Java программное обеспечение для кардиостимуляторов, где все элементы должны работать точно, как швейцарские часы, — не стоит.

Кадр: фильм «Человек-паук 2»

С другой стороны, приложения для трейдинга всё чаще пишут именно на Java. Казалось бы, где, если не в трейдинге, важен быстрый отклик — чтобы не потерять миллионы из-за скачка цен на акции Tesla? Однако на практике надёжность здесь важнее скорости: лучше торговать медленнее, но спокойно и надёжно, чем написать на С++ быструю биржу, которая через пять минут торгов крашнется. Java гарантирует безопасность, и это круто.

В истории развития любого языка программирования всегда находятся тонкие места или сомнительные решения. Java здесь не исключение, встречаются такие спорные вопросы и в спецификациях Java и JVM.

Одна из спорных тем — Project Jigsaw и система модулей, появившаяся в девятой версии Java. Создатели Java долго делали систему, которая позволяет разбивать Java-программу на отдельные логические составляющие — модули. Это дополнительный уровень абстракции над давно существующими packages в Java.

На неё потратили много времени — ведь нужно было организовать поддержку в самом языке, виртуальной машине и других частях JDK. Система долго не попадала в релизную версию, а когда всё-таки попала, оказалась, мягко говоря, не слишком востребованной пользователями.

Как в языке появляются новые фичи и спецификации? Есть специальный совет Java Community Process (JCP), который рассматривает предложения Java Specification Request (JSR) и голосует за или против. В этом совете есть представители крупных компаний, есть представители user group и даже отдельные люди — в общем, представлены интересы разных сторон Java Community.

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

Дженерики в Java, в отличие от многих других языков, — стираемые. Это означает, что все типовые параметры стираются через javac до Object. В рантайме вы не сможете понять, какой тип вам на самом деле пришёл. У этого подхода есть свои плюсы и минусы, а споры о том, что лучше — стираемые или нестираемые дженерики — продолжаются и по сей день. Тем не менее, выбор в пользу стираемых дженериков в Java сделан не случайно. Подробное обоснование, почему дженерики в Java такие, можно почитать вот в этой статье Брайана Гетца «Background: how we got the generics we have».

Но как бы вы не относились к реализации дженериков в Java, сейчас есть существенная проблема: нельзя использовать примитивные типы в качестве типовых параметров (ведь они несовместимы с Object). Это сокращает выразительную силу языка и вынуждает либо использовать Boxed-типы (что может ухудшить производительность), либо и вовсе специализировать функции под примитивные типы вручную. Исправить это собираются с помощью специализированных дженериков в рамках проекта Valhalla.

Обратная совместимость — один из главных принципов Java, которым совет JCP не пожертвует даже ради самой передовой фичи. От некоторых вещей иногда отказываются, но при этом старый код всё равно должен продолжать работать.

Например, реализация исключений через инструкции JSR/RET встречается в старом байт-коде, а в новом — нет. Но до сих пор во всех тулах нужно уметь поддерживать старый байт-код ради библиотеки, написанной 20 лет назад, но которая так и продолжает использоваться в современных проектах в виде того же старого формата .jar.

С одной стороны, этот принцип позволяет построить стабильную экосистему. Бизнес может не бояться, что выйдет новая версия, которая всё сломает и навсегда заблокирует путь к обновлению. С другой стороны, это тормозит инновации. Возможно, Java развивается медленнее, чем C#, потому, что у нас обратная совместимость — это священная корова, которую нельзя трогать.

На самом деле это очень холиварный вопрос. В основном ответ на него зависит от задач, которые хочет решать джавист.

Думаю, 30% программистов могут спокойно работать и не понимать, что происходит внутри виртуальной машины. Другим 50% достаточно на среднем уровне знать, как устроена JVM, — тогда они будут отличными мидлами и сеньорами. Их работа не в том, чтобы копаться в кишках виртуальной машины, но некоторые знания о её устройстве помогут им писать более эффективный код и избежать многих ошибок. В оставшихся 20% задач без знания деталей всё-таки не обойтись. Получается, чем лучше вы разбираетесь в виртуальной машине, тем более широкий класс задач способны решать.

Кадр: мультсериал «Футурама»

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

Java-разработчик, который регулярно погружается в эту тему, со временем сможет стать Performance Engineer. Эти специалисты находят проблемы производительности, анализируют глубинные процессы в JVM и исправляют их. Они решают проблемы не дописыванием кода в виртуальную машину, а настраивают её, как часовщики.

С точки зрения культуры всем разработчикам на managed-языках полезно знать, что происходит под капотом машины, когда они нажимают кнопку Run в IDE. Конечно, не нужно запоминать, что и в какой момент делает каждая деталь JVM. Но пройти вводный курс и понять на концептуальном уровне, что такое интерпретатор, Just In Time Compiler, что значит «умер объект» и так далее, — полезно.

Разработчик, который не знает ответов на все эти вопросы, способен решить довольно много задач. Но однажды он столкнётся с ошибками, причины которых даже не сможет понять. Например, если не задумываться, откуда берётся память и как она возвращается операционной системе, то можно получить от IDE сообщение Out of memory. А всё потому, что программа потребляет слишком много памяти. Разработчик, который знает, как устроена память, постарается оптимизировать код и не создавать горы объектов.

Сейчас довольно активно развиваются три проекта, которые рано или поздно войдут в новые версии Java.

Loom — это проект по добавлению виртуальных тредов в Java. С ним треды не мапятся на треды операционной системы, а живут сами по себе. И лишь когда их нужно исполнить, они будут садиться на треды операционки.

Раньше каждому экземпляру класса java.lang.Thread (через которые реализуется многопоточное исполнение) соответствовал один поток операционной системы. Вполне логичное решение, но есть проблема: потоков операционной системы не слишком много, поэтому вряд ли у вас получится создать больше нескольких тысяч потоков, реализованных таким образом. Project Loom предлагает альтернативу — виртуальные потоки, которые уже не связаны соотношением 1 к 1 с потоками виртуальной системы. Вместо этого они время от времени садятся на эти OS threads, чтобы выполнить очередной квант работы.

Идея не новая. Например, в Go так было всегда. Да и вообще о виртуальных тредах говорили уже много десятилетий. И даже в самом Java в 1990-е были грин-треды — схожая идея, где N зелёных потоков назначались на один поток операционной системы (тогда в процессорах было по одному ядру и проблема легковесной многопоточности не стояла так остро). Можно сказать, что Loom — это в некотором смысле реинкарнация зелёных тредов, но сделанная на более серьёзном уровне.

Этот проект очень важен, так как в современном мире микросервисов и серверов с огромным количеством одновременных подключений вам часто хотелось бы создавать десятки и сотни тысяч тредов. Со старым подходом к реализации через OS threads это просто невозможно, а вот с Loom всё получится.

Panama — это проект, посвящённый взаимодействию между Java и нативным кодом, написанным, например, на C или C++. Конечно, Java мог взаимодействовать с нативным кодом с самого рождения. Основное решение в этой области — Java Native Interface, очень мощный, но медленный и неудобный в использовании механизм. Чтобы взаимодействовать с нативами, приходилось писать некрасивый, громоздкий и, что самое главное, небезопасный код. Я уверен, что любому джависту, который хоть что-нибудь делал с JNI, как минимум не понравилось, а как максимум — он до сих видит кошмары про развалы в JNI.

Чтобы избавить Java-разработчиков от ночных кошмаров, авторы Panama уже много лет работают над своим проектом, который, как Панамский канал, соединяет два мира: нативный и Java. Panama предлагает новый интерфейс и его оптимизированную реализацию на стороне JVM, которая позволит приятно и безопасно работать с нативным кодом, в том числе с off-heap.

Проект Valhalla посвящён введению в Java новых типов объектов, так называемых value-типов, или inline-типов, или же primitive-value-типов — это текущее название. Да, проект настолько сложный, что даже основная его концепция часто меняет имя!

Если коротко, то смысл в том, чтобы выделить подкласс объектов, у которых нет identity. Что это такое? В Java вы можете создать два абсолютно одинаковых объекта с помощью оператора new. Потом сравнить их на == и получить false. Это разные объекты! Они сравниваются не по содержимому (которое одинаковое), а по некоторому уникальному свойству, назначаемому каждому объекту при создании. Вот возможность сравнивать не по содержимому, а по чему-то ещё — это и есть identity.

С другой стороны, можно объявить две переменные типа int, записать в каждую из них значение 42, сравнить на == и получить результат true. Всё потому, что у int никакого identity нет, они сравниваются по содержимому.

Цель Valhalla — дать пользователям возможность самим описывать классы, у которых нет identity, и подготовить к этому уже существующую типовую систему. Как следствие, можно будет, например, заводить плоские поля таких типов внутри других классов (то есть фактически инлайнить их поля внутрь других объектов), работать с плоскими массивами таких объектов и даже получить специализированные дженерики.

Это огромное, фундаментальное изменение всей платформы Java, за которым очень интересно следить и которого стоит ожидать, ведь оно принесёт множество возможностей обычным разработчикам.

Сами виртуальные машины Java обычно пишут на С++, стандартная библиотека же в основном написана на самом Java (хотя иногда и приходится уходить в нативный код, то есть снова в плюсы). Вообще, так повелось, что системщину пишут на плюсах, ведь здесь, с одной стороны, важна производительность, а с другой — связь с низким уровнем, с операционной системой и железом. В то же время стало очевидно, что далеко не все компоненты виртуальной машины обязательно нужно писать на С++. Например, зачем делать компилятор на С++, если есть замечательные managed-языки вроде Java или Scala?

Вот, например, в Oracle Labs разрабатывает проект GraalVM. Он состоит из трёх компонентов:

  • Компилятор Graal — мощный оптимизирующий компилятор, в будущем он, возможно, заменит компилятор C2 из HotSpot. Он не уступает по качеству многих оптимизаций, но написан полностью на Java.
  • Truffle Framework — специальный фреймворк для написания интерпретаторов других языков, которые потом запускаются на GraalVM. По сути, это быстрый способ реализовать любой язык программирования на базе GraalVM! Опять-таки, интерпретаторы пишутся на managed-языках.
  • Graal Native Image — отдельный режим сборки приложений, который на самом деле представляет из себя целую виртуальную машину, но написанную с некоторыми нарушениями спецификации. Зато она позволяет получить быстрый стартап и низкое потребление памяти. Рантайм для такой виртуальной машины тоже частично написан на Java! Понятно, что не полностью и с разными ограничениями языка (на самом деле там используется отдельный диалект — System Java), но тем не менее это возможно.

Вообще, писать виртуальные машины на managed-языках — давняя мечта системщиков. Ведь, например, компилятор С написан на С? Вот и разработчики виртуальных машин для managed-языков хотят писать их на Java или других managed-языках, а не на опасном и болезненном С++.

Для начала скажу, что я никогда не контрибьютил в OpenJDK, а занимался разработкой другой, проприетарной и закрытой JVM. Поэтому о процедуре коммита в OpenJDK имею только смутное представление, так что написанному ниже доверяйте на свой страх и риск!

Если бы я задался целью контрибьютить в OpenJDK, то думал бы в двух направлениях:

  • Найти что-то небольшое, что получится исправить или улучшить. Это может быть несложный (и низкоприоритетный) баг в багтрекере OpenJDK или неэффективность какого-нибудь алгоритма в платформенных классах. Исправьте эту проблему, соберите OpenJDK и проверьте, что, например, алгоритм и правда стал работать лучше на каких-нибудь бенчмарках.

Потом напишите в мейлинг-лист, расскажите о сути улучшения и попросите сделать ревью. Наконец, пройдите его, а затем и остальную процедуру коммита. Насколько я знаю, она довольно стандартная, ведь OpenJDK теперь находится на GitHub. Поздравляю, теперь вы — контрибьютор в OpenJDK!

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

  • Устроиться на работу в компанию-контрибьютор. В этом случае вы будете разрабатывать код, который попадёт в OpenJDK, в рабочее время. Однако сложность в том, что таких компаний всё-таки очень мало. Зато попасть в одну из них — действительно круто. Яркий пример такой компании — питерская BellSoft, которая в прошлом году заняла четвёртое место в мире (!) среди внешних (не из Oracle) контрибьюторов в OpenJDK.

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

Мейлинг-лист — это такой почтовый ящик, на который можно подписаться. Подписчики мейлинг-листа получают письма из общей рассылки, но ещё могут отвечать, участвовать в дискуссиях или задавать вопросы. Именно так и общаются разработчики многих языков программирования.

Мейлинг-листов про Java и JVM довольно много, есть свои мейлинг-листы для разных компонентов JDK и разных подпроектов в OpenJDK. Например, есть отдельные мейлинг-листы для упомянутых выше проектов Loom или Valhalla. Так что тут главное — выбрать темы, которые вам интересны, а потом найти соответствующие мейлинг-листы на сайте сообщества Java.

Новые предложения по технологии в первую очередь пишут и обсуждают именно в мейлинг-листах, поэтому в них отражается история развития Java и JVM. Такой канал связи действительно работает, хоть и может показаться немного устаревшим. Если хотите узнать сложные детали, например как работает конкретная часть виртуальной машины, советую подписаться на соответствующий мейлинг-лист.

Более привычный и простой для восприятия источник информации — конференции. Разработчики JVM регулярно выступают с докладами, в которых по косточкам разбирают детали реализации, при этом в доступной и понятной форме.

Наибольшая концентрация знаний — на ежегодной конференции Java Virtual Machine Language Summit. Видео выступлений можно посмотреть на YouTube-канале Java. Очень много хардкорных и качественных докладов от разработчиков JVM есть на российских конференциях Joker и JPoint от компании JUG Ru Group.

Сами мы (JUGNsk) тоже организуем свою Java-конференцию SnowOne в Новосибирске. В нашем программном комитете много системщиков, поэтому докладам о внутренностях виртуальных машин на конференции уделяется особое внимание.

Ещё один источник свежей информации — Twitter. Часто там появляются последние новости о Java вообще и JVM в частности. Из англоязычных авторов советую подписаться на аккаунты Брайана Гетца и Марка Рейнхольда — архитекторов языка Java и Java-платформы.

В России тоже есть суперзвёзды и разработчики JVM, например Алексей Шипилёв. Он один из главных контрибьюторов Shenandoah GC, работал в Oracle, а сейчас — в Red Hat. При этом он пишет классные посты (чего стоит одна только серия JVM Anatomy Quarks!) и выступает с отличными докладами о том, как устроена JVM изнутри.

Ещё всегда интересно читать Сергея Куксенко — перформанс-инженера в Oracle. Он разгоняет многие фичи, которые появляются в Java, и интересно об этом рассказывает. А новости о HotSpot и Panama можно найти в аккаунте Владимира Иванова.

В целом в Twitter есть ещё огромное количество как русскоязычных, так и англоязычных крутых инженеров, связанных с разработкой JVM. Так что принцип здесь такой же, как с мейлинг-листами: находите человека, участвующего в определённом проекте в OpenJDK (или за его пределами), и смело подписываетесь!

Резюме:

  • Чтобы решать рутинные задачи, джависту не нужно разбираться в деталях JVM. Но перейти на следующий уровень не получится, если хотя бы на концептуальном уровне не понимать, как работает интерпретатор, что такое Just In Time Compilation, как устроена память и так далее.
  • JDK — это комплект инструментов Java-разработчика. В него входит: javac, сама виртуальная машина, стандартная библиотека классов и документация. OpenJDK — это эталонная версия JDK с полностью открытым исходным кодом. Основные контрибьюторы в этот проект — это Oracle, но кроме неё есть и много других компаний и разработчиков, которые вносят свой вклад.
  • Обычно виртуальные машины пишут на языках C/C++. Но уже есть проекты, в которых JVM, компилятор и рантайм почти полностью написаны на Java или его диалекте.
  • Контрибьютить в OpenJDK может любой желающий, но серьёзные изменения в JVM обычно вносят опытные разработчики. Тем не менее возможно найти себе небольшие задачи, с которых и начать этот путь.

Научитесь: Профессия Java-разработчик
Узнать больше

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

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

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

Абстракция и виртуализация

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

Рис. 1. Абстракция и виртуализация в применении к дисковой памяти: (а) абстракция поддерживает упрощенный интерфейс к базовым ресурсам; (б) на данном уровне абстракции виртуализация обеспечивает альтернативный интерфейс к ресурсам и организацию их разделения

На рис. 1 (а) приведен пример абстракции в применении к дисковой памяти. Операционная система абстрагируется от тонкостей адресации на жестком диске, от его секторов и дорожек, чтобы для прикладной программы диск выглядел как набор файлов переменного размера. Опираясь на эту абстракцию, «прикладные» программисты могут создавать файлы, записывать и читать данные, не зная устройства и физической организации жесткого диска.

Концепция архитектуры системы команд компьютера (instruction set architecture, ISA) наглядно иллюстрирует преимущества хорошо определенных интерфейсов. Они позволяют разрабатывать взаимодействующие компьютерные подсистемы не только в разных организациях, но и в разные периоды, иногда разделенные годами. Например, Intel и AMD создают микропроцессоры с системой команд IA-32 (x86), в то время как разработчики Microsoft пишут программное обеспечение, которое компилируется в эту систему команд. Поскольку обе стороны соблюдают спецификацию ISA, можно ожидать, что программное обеспечение будет правильно выполняться любым ПК на базе микропроцессора с архитектурой IA-32.

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

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

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

Виртуальные машины

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

Встроенные системные интерфейсы

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

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

Рис. 2. Архитектура компьютерной системы. Вертикальные связи между ключевыми уровнями реализации обеспечиваются архитектурой системы команд (ISA), двоичным интерфейсом приложений (ABI) и интерфейсом прикладного программирования (API)

На рис. 2 показаны некоторые важные интерфейсы и уровни реализации в типичной компьютерной системе. Три таких интерфейса (расположенных на границе между оборудованием и программным обеспечением) являются особенно важными для построения ВМ: это архитектура системы команд (ISA), двоичный интерфейс приложений (application binary interface, ABI) и интерфейс прикладного программирования (application programming interface, API).

Архитектура системы команд. ISA определяет границу между оборудованием и программным обеспечением и состоит из двух интерфейсов, обозначенных на рис. 2 цифрами 3 и 4. Интерфейс 4 представляет собой пользовательскую часть ISA и содержит функции, доступные прикладной программе. Интерфейс 3 (системная часть ISA) кроме пользовательских команд содержит функции, доступные только компонентам операционной системы, которые отвечают за управление оборудованием.

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

Интерфейс прикладного программирования. API предоставляет программе аппаратные ресурсы и услуги через пользовательскую часть ISA (интерфейс 4), дополненную обращениями к библиотекам на языке высокого уровня (интерфейс 1). Все вызовы системных процедур обычно выполняются через библиотеки. Использование API позволяет путем перекомпиляции легко переносить прикладные программы на другие системы, поддерживающие тот же интерфейс прикладного программирования.

Процессные и системные виртуальные машины

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

С точки зрения процесса, обеспечивающего выполнение пользовательской программы, машина состоит из выделенного процессу логического адресного пространства, команд пользовательского уровня и регистров, которые позволяют выполнять код этого процесса. Устройства ввода/вывода доступны лишь через операционную систему, и для процесса есть только один способ взаимодействия с системой ввода/вывода — вызовы системных процедур. Таким образом, применительно к процессу машину определяет интерфейс ABI. А интерфейс API определяет характеристики машины с точки зрения прикладной программы, написанной на высокоуровневом языке.

С точки зрения операционной системы она целиком выполняется на базовой машине. Опе?рационная система — полнофункциональная среда исполнения, которая поддерживает множество процессов, совместно использующих файловую систему и другие средства ввода/вывода. Но процессы «приходят и уходят», а системная среда остается. Система выделяет процессам реальную память и устройства ввода/вывода, позволяет им взаимодействовать с этими ресурсами. Следовательно, применительно к операционной системе машину определяют лишь характеристики базовых аппаратных средств, а интерфейс между системой и машиной обеспечивает ISA.

Поскольку процессы и система «видят» машину по-разному, виртуальные машины бывают процессными и системными. Процессная ВМ — это виртуальная платформа для выполнения отдельного процесса; она предназначена исключительно для его поддержки, создается при активизации процесса и прекращает свое существование с его окончанием. Системная ВМ предоставляет полнофункциональную, постоянно действующую системную среду для поддержки операционной системы вместе с множеством ее пользовательских процессов; она обеспечивает «гостевой» операционной системе доступ к виртуальным аппаратным средствам, в том числе к процессору и памяти, устройствам ввода/вывода, а иногда — и к графическому интерфейсу.

Процесс или система, выполняемая на ВМ, называется гостем, а базовая платформа, поддерживающая ВМ, — хостом. Программное обеспечение виртуализации, реализующее процессную ВМ, часто для краткости именуют рабочей средой. Программное обеспечение виртуализации системной ВМ обычно называют монитором виртуальных машин (virtual machine monitor, VMM).

Рис. 3. Процессные и системные виртуальные машины: (а) программное обеспечение виртуализации процессной ВМ преобразует системные вызовы и машинные команды пользовательского уровня в соответствующие вызовы и команды другой программно-аппаратной платформы; (б) в системной ВМ программное обеспечение виртуализации преобразует машинные команды одной аппаратной платформы в команды для другой

На рис. 3 представлены процессная и системная ВМ. Волнистыми линиями обозначены совместимые интерфейсы. В процессной виртуальной машине программное обеспечение виртуализации находится на уровне интерфейсов ABI или API, над границей между операционной системой и оборудованием. Среда исполнения (runtime) эмулирует как команды пользовательского уровня, так и вызовы системных процедур и обращения к библиотекам. В системной виртуальной машине программное обеспечение виртуализации находится между аппаратными средствами хост-машины и гостевым программным обеспечением. Монитор VMM может эмулировать аппаратную архитектуру ISA, отличную от ISA хоста, чтобы гостевое программное обеспечение могло выполнять другую систему команд. Однако во многих реализациях системных ВМ монитор VMM не занимается эмуляцией команд; его основная роль состоит скорее в виртуализации аппаратных средств.

Процессные виртуальные машины

Процессные ВМ создают виртуальные среды ABI или API для пользовательских приложений. Различные их разновидности позволяют в многозадачном режиме осуществлять репликацию операционной среды, эмулировать систему команд, оптимизировать код или выполнять программы на языках высокого уровня.

Многозадачные системы

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

Интерпретаторы и динамические трансляторы двоичного кода

Более сложной проблемой для процессных ВМ является поддержка программ в двоичном коде, которые скомпилированы для системы команд, отличающейся от системы команд хоста. Свежий пример процессной ВМ — программный пакет Intel IA32-EL [1], позволяющий на платформе Itanium выполнять приложения, рассчитанные на IA-32.

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

Оптимизаторы двоичного кода

Для повышения производительности динамические трансляторы иногда оптимизируют двоичный код. Эта возможность приводит к идее создания виртуальной машины, в которой гость и хост используют одну и ту же систему команд. Единственным назначением такой ВМ становится оптимизация двоичного кода. Оптимизаторы используют информацию из профиля, собранную при интерпретации или трансляции, чтобы оптимизировать двоичный код «на лету». Примером такого оптимизатора является система Dynamo — один из результатов реализации научно-исследовательского проекта компании Hewlett-Packard [2].

Виртуальные машины для языков высокого уровня

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

Рис. 4. Среды языка высокого уровня: (а) в традиционной среде распространяется зависимый от платформы объектный код; (б) в среде ВМ языка высокого уровня зависимая от платформы виртуальная машина выполняет переносимый промежуточный код

Рис. 4 показывает различия между обычной средой компиляции, зависящей от платформы, и средой ВМ языка высокого уровня. В обычной среде (рис. 4(а)) препроцессор транслятора генерирует промежуточный код, подобный машинному, но более абстрактный. Затем генератор кода на его основе создает двоичный файл с машинным кодом для конкретной операционной системы и архитектуры ISA. Этот файл может выполняться на платформах, поддерживающих данную комбинацию ISA/операционная система.

В ВМ языка высокого уровня (рис. 4(б)) транслятор генерирует абстрактный машинный код для виртуальной ISA, которая определяет интерфейс ВМ. Этот виртуальный код вместе с сопутствующими метаданными (информацией о структурах данных) распространяется для выполнения на различных платформах. На каждой из них установлена ВМ, способная загрузить и выполнить команды виртуальной ISA, а также имеется набор библиотечных подпрограмм, предписанный стандартизированным API. Простейший вариант такой ВМ представляет собой интерпретатор. Более сложные высокопроизводительные ВМ транслируют абстрактный код в машинный для непосредственного выполнения на базовой платформе.

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

Известными примерами ВМ языка высокого уровня являются архитектура виртуальной машины Java компании Sun Microsystems [3] и среда Microsoft Common Language Infrastructure, на которой основана платформа .NET Framework [4]. В обеих системах применяются стековые архитектуры ISA, что позволяет устранить необходимость в регистрах, использовать абстрактную спецификацию данных и модель памяти, поддерживающие безопасное объектно-ориентированное программирование.

Системные виртуальные машины

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

Системные ВМ появились в середине 60-х годов [5]. В то время компьютерные системы на базе мэйнфреймов были очень большими и дорогими, обычно обслуживали многочисленные группы пользователей. С появлением технологий ВМ эти группы получили возможность на общем оборудовании эксплуатировать различные операционные системы. По мере снижения цен на компьютерное оборудование и развития настольных ПК интерес к первым системным ВМ постепенно снизился. Однако сегодня системные ВМ снова набирают популярность, поскольку на смену мэйнфреймам пришли серверы и серверные комплексы, обслуживающие большие группы потребителей.

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

В системной ВМ монитор VMM обеспечивает репликацию платформы. Основной проблемой является распределение аппаратных ресурсов между несколькими гостевыми операционными системами (примером служит виртуализация диска, показанная на рис. 1). VMM управляет всеми аппаратными ресурсами. Гостевая операционная система и ее прикладные процессы работают под скрытым контролем VMM. Когда гостевая ОС пытается выполнить привилегированную команду или операцию, непосредственно затрагивающую общие аппаратные ресурсы, VMM ее перехватывает, проверяет правильность и исполняет от имени гостя. Гостевое ПО «не знает» об этой негласной работе.

Классические системные ВМ

Большинство системных ВМ обеспечивают примерно одинаковые функциональные возможности, но различаются деталями реализации. При классическом подходе [6] монитор VMM устанавливается на «голом железе», а ВМ располагается поверх него. VMM выполняется в привилегированном режиме, в то время как гостевые операционные системы лишены почти всех привилегий. Это необходимо, чтобы VMM мог перехватывать и эмулировать те их действия, которые в обычных условиях связаны с управлением жизненно важными аппаратными ресурсами.

Вложенные ВМ

В альтернативной реализации системной ВМ программное обеспечение виртуализации располагается поверх существующей хост-системы. Такая ВМ называется вложенной. Преимущество вложенных ВМ состоит в том, что пользователь устанавливает их точно так же, как любую прикладную программу. Чтобы получить доступ к драйверам устройств и другим низкоуровневым услугам, программное обеспечение виртуализации обращается к хост-системе, а не к VMM. Примером вложенной ВМ может служить сервер VMware GSX Server [7], который выполняется на аппаратной платформе IA-32.

Интегральные ВМ

В обычных системных ВМ хост-система, все гостевые операционные системы и прикладные программы используют архитектуру ISA базового оборудования. Однако в некоторых ситуациях гость и хост не имеют общей ISA. Например, две самые популярные настольные системы, Windows PC и Apple PowerPC, используют различные ISA и разные операционные системы.

Интегральные ВМ справляются с такой ситуацией, виртуализируя все программное обеспечение, в том числе операционную систему и приложения. Из-за различий в системах команд ВМ должна эмулировать и код приложений, и код операционной системы. Примером ВМ такого типа служит эмулятор Virtual PC [8], в котором система Windows работает на платформе Macintosh. Программное обеспечение ВМ выполняется на хосте как обычная прикладная программа и не использует системных операций ISA.

Многопроцессорная виртуализация

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

С помощью физического разбиения на разделы [9] аппаратные ресурсы, используемые одной виртуальной системой, отделяются от ресурсов других виртуальных систем. Физическое разделение обеспечивает высокую степень изоляции, поэтому ни проблемы ПО, ни ошибки аппаратных средств в одном разделе не затрагивают программы в других разделах. При логическом разбиении на разделы [10] разделы сервера совместно используют базовые аппаратные ресурсы в режиме временного мультиплексирования, что позволяет повысить коэффициент загрузки оборудования. Однако при этом теряются некоторые из преимуществ изоляции аппаратных средств.

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

Встроенные ВМ

Функциональность и мобильность — вот цели большинства системных ВМ, реализованных на уже имеющихся аппаратных средствах со стандартной архитектурой ISA. В отличие от них, встроенные ВМ реализуют новые частные архитектуры, нацеленные на повышение производительности и эффективности работы. ISA хост-машины может быть полностью новой или расширять возможности существующей.

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

Наиболее известный пример встроенной ВМ — процессор Transmeta Crusoe [11]. Его базовые аппаратные средства используют архитектуру команд со сверхдлинным командным словом (very long instruction word, VLIW), а гостевая ISA — это Intel IA-32. Благодаря простоте аппаратной части, предназначенной для выполнения команд VLIW, разработчикам Transmeta удалось существенно снизить энергопотребление процессора.

В системе IBM AS/400 (сегодня известна как iSeries) также используется технология встроенных ВМ [12]. В отличие от других встроенных ВМ, основное назначение AS/400 — поддержка объектно-ориентированной системы команд, позволяющей по-новому взглянуть на интерфейс между оборудованием и программным обеспечением. Сегодняшние реализации AS/400 основаны на расширенной архитектуре PowerPC, тогда как ранние версии использовали существенно отличавшуюся от нее частную архитектуру ISA.

Систематика виртуальных машин

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

Рис. 5. Классификация виртуальных машин. В категориях процессных и системных ВМ основным дифференцирующим признаком является эмуляция ISA

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

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

Категория системных ВМ без эмуляции ISA объединяет классические и вложенные ВМ, служащие для репликации изолированной системной среды. Основное различие между ними состоит в реализации монитора VMM, а не в функциональных возможностях.

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

***

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

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

Литература

  1. L. Baraz et al, IA-32 Execution Layer: A Two-Phase Dynamic Translator Designed to Support IA-32 Applications on Itanium-Based Systems. Proc. 36th Ann. IEEE/ACM Intl Symp. Microarchitecture, IEEE CS Press, 2003.
  2. V. Bala, E. Duesterwald, S. Banerjia, Dynamo: A Transparent Dynamic Optimization System. Proc. ACM SIGPLAN 2000 Conf. Programming Language Design and Implementation, ACM Press, 2000.
  3. T. Lindholm, F. Yellin, The Java Virtual Machine Specification, 2nd ed. Addison-Wesley, 1999.
  4. D. Box, Essential .NET, Volume 1: The Common Language Runtime. Addison-Wesley, 2002.
  5. R.J. Creasy, The Origin of the VM/370 Time-Sharing System. IBM Journal Research and Development, Sept. 1981.
  6. R.P. Goldberg, Survey of Virtual Machine Research. Computer, June 1974.
  7. J. Sugerman, G. Venkitachalam, B-H. Lim, Virtualizing I/O Devices on VMware Workstations Hosted Virtual Machine Monitor. Proc. General Track: 2001 Usenix Ann. Technical Conf., Usenix Assoc., 2001.
  8. E. Traut, Building the Virtual PC. Byte, Nov. 1997.
  9. Sun Enterprise 10000 Server: Dynamic System Domains. Sun Microsystems, Tech. white paper, 1999.
  10. T.L. Borden, J.P. Hennessy, J.W. Rymarczyk, Multiple Operating Systems on One Processor Complex. IBM Systems Journal, Jan. 1989.
  11. A. Klaiber, The Technology Behind Crusoe Processors: Low-Power x86-Compatible Processors Implemented with Code Morphing Software. Tech. brief, Transmeta, 2000.
  12. E. Soltis, Inside the AS/400. Duke Press, 1996.

Джеймс Смит (atjes@ece.tvisc.edu) — профессор факультета электротехники и вычислительной техники в университете Висконсина. Рави Наир (nair@us.ibm.com) — научный сотрудник исследовательского центра IBM Watson Research Center.


James Smith, Ravi Nair. The Architecture of Virtual Machines. IEEE Computer, May 2005. IEEE Computer Society, 2005. All rights reserved. Reprinted with permission.

В вычислительной технике виртуальная машина ( ВМ ) — это виртуализация / эмуляция компьютерной системы . Виртуальные машины основаны на компьютерных архитектурах и обеспечивают функциональность физического компьютера. Их реализации могут включать специализированное оборудование, программное обеспечение или их комбинацию. Виртуальные машины различаются и организованы по их функциям, как показано здесь:

  • Системные виртуальные машины (также называемые виртуальными машинами полной виртуализации ) заменяют реальную машину. Они обеспечивают функциональность, необходимую для запуска целых операционных систем . Гипервизориспользует собственное выполнение для совместного использования оборудования и управления им, что позволяет использовать несколько сред , изолированных друг от друга, но существующих на одной физической машине. Современные гипервизоры используют виртуализацию с аппаратной поддержкой , специальное оборудование для виртуализации, в основном за счет центральных процессоров.
  • Виртуальные машины процессов предназначены для выполнения компьютерных программ в независимой от платформы среде.

Некоторые эмуляторы виртуальных машин, такие как QEMU и эмуляторы игровых консолей , также предназначены для эмуляции (или «виртуальной имитации») различных системных архитектур, что позволяет выполнять программные приложения и операционные системы, написанные для другого процессора или другой архитектуры. Виртуализация на уровне операционной системы позволяет разделять ресурсы компьютера через ядро . Термины не являются универсально взаимозаменяемыми.

Определения

Системные виртуальные машины

Первоначально Попек и Голдберг определили «виртуальную машину» как «эффективную изолированную копию реальной компьютерной машины». Текущее использование включает в себя виртуальные машины, которые не имеют прямого соответствия какому-либо реальному оборудованию. Физическое «реальное» оборудование, на котором работает виртуальная машина, обычно называется «хостом», а виртуальная машина, эмулируемая на этой машине, обычно называется «гостем». Хост может эмулировать несколько гостей, каждый из которых может эмулировать разные операционные системы и аппаратные платформы.

Желание запускать несколько операционных систем было первоначальным мотивом для виртуальных машин, чтобы обеспечить разделение времени между несколькими однозадачными операционными системами. В некоторых отношениях системную виртуальную машину можно считать обобщением исторически предшествовавшей ей концепции виртуальной памяти . IBM CP/CMS , первые системы, допускающие полную виртуализацию , реализовали разделение времени , предоставив каждому пользователю однопользовательскую операционную систему, Conversational Monitor System (CMS). В отличие от виртуальной памяти, системная виртуальная машина давала пользователю право писать в своем коде привилегированные инструкции. Такой подход имел определенные преимущества, такие как добавление устройств ввода/вывода, не разрешенных стандартной системой.

По мере развития технологии виртуальной памяти для целей виртуализации могут применяться новые системы избыточного выделения памяти для управления совместным использованием памяти несколькими виртуальными машинами в одной компьютерной операционной системе. Возможно совместное использование страниц памяти с идентичным содержимым несколькими виртуальными машинами, работающими на одной физической машине, что может привести к их отображению на одну и ту же физическую страницу с помощью метода, называемого слиянием одной и той же страницы ядра (KSM). Это особенно полезно для страниц, доступных только для чтения, таких как страницы, содержащие сегменты кода, например, для нескольких виртуальных машин, на которых запущено одно и то же или похожее программное обеспечение, программные библиотеки, веб-серверы, компоненты промежуточного программного обеспечения и т. д. Гостевые операционные системы не нуждаются в быть совместимым с аппаратным обеспечением хоста, что позволяет запускать разные операционные системы на одном компьютере (например, Windows , Linux или предыдущие версии операционной системы) для поддержки будущего программного обеспечения.

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

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

Обрабатывать виртуальные машины

Виртуальная машина процесса, иногда называемая виртуальной машиной приложения или управляемой средой выполнения (MRE), запускается как обычное приложение внутри основной ОС и поддерживает один процесс. Он создается при запуске этого процесса и уничтожается при выходе из него. Его цель — предоставить независимую от платформы среду программирования, которая абстрагирует детали базового оборудования или операционной системы и позволяет программе выполняться одинаково на любой платформе.

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

Этот тип ВМ стал популярен благодаря языку программирования Java , который реализован с использованием виртуальной машины Java . Другие примеры включают виртуальную машину Parrot и .NET Framework , которая работает на виртуальной машине, называемой Common Language Runtime . Все они могут служить слоем абстракции для любого компьютерного языка.

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

В отличие от других виртуальных машин процессов, эти системы не предоставляют определенного языка программирования, а встроены в существующий язык; обычно такая система обеспечивает привязки для нескольких языков (например, C и Fortran ). Примерами являются параллельная виртуальная машина (PVM) и интерфейс передачи сообщений (MPI). Они не являются строго виртуальными машинами, поскольку приложения, работающие поверх них, по-прежнему имеют доступ ко всем службам ОС и, следовательно, не ограничиваются системной моделью.

История

Как системные виртуальные машины, так и виртуальные машины процессов относятся к 1960-м годам и продолжают активно развиваться.

Системные виртуальные машины выросли из разделения времени , что, в частности, реализовано в совместимой системе разделения времени (CTSS). Разделение времени позволяло нескольким пользователям одновременно использовать компьютер : казалось, что каждая программа имеет полный доступ к машине, но в каждый момент времени выполняется только одна программа, при этом система переключается между программами во временных интервалах, сохраняя и восстанавливая состояние каждый раз. Это превратилось в виртуальные машины, в частности, благодаря исследовательским системам IBM: M44/44X , которые использовали частичную виртуализацию , а также CP-40 и SIMMON , которые использовали полную виртуализацию и были ранними примерами гипервизоров . Первой широко доступной архитектурой виртуальной машины была CP-67 /CMS ( подробности см. в разделе «История CP/CMS» ). Важным отличием было использование нескольких виртуальных машин в одной хост-системе для разделения времени, как в M44/44X и CP-40, и использование одной виртуальной машины в хост-системе для прототипирования, как в SIMMON. Эмуляторы с аппаратной эмуляцией более ранних систем для совместимости восходят к IBM System / 360 1963 года, а программная эмуляция (тогда называемая «симуляцией») предшествует ей.

Процессные виртуальные машины изначально возникли как абстрактные платформы для промежуточного языка , используемого в качестве промежуточного представления программы компилятором ; ранние примеры датируются примерно 1966 годом. Примером раннего 1966 года была машина O-кода , виртуальная машина, которая выполняет O-код (объектный код), создаваемый внешним интерфейсом компилятора BCPL . Эта абстракция позволила легко перенести компилятор на новую архитектуру за счет реализации новой серверной части , которая брала существующий O-код и компилировала его в машинный код для базовой физической машины. Язык Euler использовал аналогичный дизайн с промежуточным языком P (portable). Это было популяризировано около 1970 года Паскалем , особенно в системе Pascal-P (1973) и компиляторе Pascal-S (1975), в которых он был назван p-кодом , а результирующая машина — машиной p-кода . Это оказало влияние, и в этом смысле виртуальные машины часто обычно называют машинами с p-кодом. Помимо того, что это промежуточный язык, p-код Pascal также выполнялся непосредственно интерпретатором, реализующим виртуальную машину, особенно в UCSD Pascal (1978); это повлияло на более поздние интерпретаторы, особенно на виртуальную машину Java (JVM). Другим ранним примером был SNOBOL4 (1967), который был написан на языке реализации SNOBOL (SIL), языке ассемблера для виртуальной машины, который затем был нацелен на физические машины путем транспиляции в их родной ассемблер через макроассемблер . Однако с тех пор макросы потеряли популярность, поэтому этот подход оказался менее влиятельным. Виртуальные машины процессов были популярным подходом к реализации раннего программного обеспечения для микрокомпьютеров, включая Tiny BASIC и приключенческие игры, от одноразовых реализаций, таких как Pyramid 2000, до движка общего назначения, такого как z-machine Infocom , который, по утверждению Грэма Нельсона , «возможно, самая портативная виртуальная машина из когда-либо созданных».

Значительные успехи произошли в реализации Smalltalk -80, особенно в реализации Deutsch/Schiffmann, которая продвинула компиляцию точно в срок (JIT) как подход к реализации, использующий виртуальную машину процесса. Позже известными виртуальными машинами Smalltalk были VisualWorks , Squeak Virtual Machine и Strongtalk . Родственным языком, который произвел много инноваций в области виртуальных машин, был язык программирования Self , который впервые применил адаптивную оптимизацию и сборку мусора поколений . Эти методы оказались коммерчески успешными в 1999 году в виртуальной машине HotSpot Java. Другие новшества включают в себя виртуальную машину на основе регистров, чтобы лучше соответствовать базовому оборудованию, а не виртуальную машину на основе стека, которая больше соответствует языку программирования; в 1995 году это было впервые реализовано с помощью виртуальной машины Dis для языка Limbo . OpenJ9 является альтернативой HotSpot JVM в OpenJDK и представляет собой проект eclipse с открытым исходным кодом, требующий лучшего запуска и меньшего потребления ресурсов по сравнению с HotSpot.

Полная виртуализация

Логическая схема полной виртуализации

При полной виртуализации виртуальная машина имитирует достаточно оборудования, чтобы позволить немодифицированной «гостевой» ОС (разработанной для того же набора инструкций ) работать изолированно. Впервые этот подход был применен в 1966 году с IBM CP-40 и CP-67 , предшественниками семейства VM .

Примеры вне области мейнфреймов включают Parallels Workstation , Parallels Desktop для Mac , VirtualBox , Virtual Iron , Oracle VM , Virtual PC , Virtual Server , Hyper-V , VMware Fusion , VMware Workstation , VMware Server (снят с производства, ранее назывался GSX Server), VMware Технология ESXi , QEMU , Adeos , Mac-on-Linux, Win4BSD, Win4Lin Pro и Egenera vBlade.

Аппаратная виртуализация

В аппаратной виртуализации аппаратное обеспечение обеспечивает архитектурную поддержку, которая упрощает создание монитора виртуальной машины и позволяет изолированно запускать гостевые ОС. Аппаратная виртуализация была впервые представлена ​​в IBM System/370 в 1972 году для использования с VM/370 , первой операционной системой для виртуальных машин, предлагаемой IBM в качестве официального продукта.

В 2005 и 2006 годах Intel и AMD предоставили дополнительное оборудование для поддержки виртуализации. Sun Microsystems (теперь Oracle Corporation ) добавила аналогичные функции в свои процессоры UltraSPARC T-Series в 2005 году. Примеры платформ виртуализации, адаптированных к такому оборудованию, включают KVM , VMware Workstation , VMware Fusion , Hyper-V , Windows Virtual PC , Xen , Parallels Desktop для Mac , Oracle VM Server для SPARC , VirtualBox и Parallels Workstation .

В 2006 году было обнаружено, что поддержка 32- и 64-разрядного оборудования x86 первого поколения редко дает преимущества в производительности по сравнению с программной виртуализацией.

Виртуализация на уровне операционной системы

При виртуализации на уровне операционной системы физический сервер виртуализируется на уровне операционной системы, что позволяет нескольким изолированным и безопасным виртуализированным серверам работать на одном физическом сервере. Среды «гостевой» операционной системы используют тот же запущенный экземпляр операционной системы, что и хост-система. Таким образом, одно и то же ядро ​​операционной системы также используется для реализации «гостевой» среды, и приложения, работающие в данной «гостевой» среде, рассматривают ее как автономную систему. Пионерской реализацией были тюрьмы FreeBSD ; другие примеры включают Docker , контейнеры Solaris , OpenVZ , Linux-VServer , LXC , разделы рабочей нагрузки AIX , контейнеры Parallels Virtuozzo и виртуальные учетные записи iCore .

Смотрите также

  • Образ машины Amazon
  • Виртуализация рабочего стола
  • Контейнеры Linux
  • Родной комплект для разработки
  • Паравиртуализация
  • Гипервизор хранилища
  • Универсальная машина Тьюринга
  • Виртуальное устройство
  • Виртуальное устройство резервного копирования
  • Образ виртуального диска
  • Виртуальная машина DOS (VDM)
  • Побег из виртуальной машины

Рекомендации

дальнейшее чтение

  • Джеймс Э. Смит, Рави Наир, Виртуальные машины: универсальные платформы для систем и процессов , Морган Кауфманн, май 2005 г., ISBN  1-55860-910-5 , 656 страниц (охватывает виртуальные машины процессов и систем)
  • Крейг, Иэн Д. Виртуальные машины . Springer , 2006, ISBN  1-85233-969-1 , 269 страниц (охватывает только виртуальные машины процессов)

Внешние ссылки

  • Мендель Розенблюм (31 августа 2004 г.). «Реинкарнация виртуальных машин» . Очередь АСМ . Том. 2, нет. 5.
  • Sandia National Laboratories использует 1 миллион ядер Linux в качестве виртуальных машин
  • Дизайн виртуальной машины Inferno от Фила Уинтерботтома и Роба Пайка

Понравилась статья? Поделить с друзьями:
  • Ацц 600 мг таблетки инструкция по применению цена отзывы
  • Мануал volvo xc90 2008
  • Комплект лабораторного оборудования для наблюдения за погодой с руководством для учителя
  • Wanbo projector t6 max инструкция на русском
  • Крем заживин инструкция по применению взрослым