Концепция виртуальной машины – один из лучших стимуляторов воображения, которые пришли к нам из компьютерной науки. Она успела доказать свою состоятельность в сфере информатики, и теперь ее пора применять в других сферах. Я использую этот термин в более широком смысле (и в свое время я объясню почему), поэтому не лишним будет узнать, каково его изначальное – как скажут некоторые, истинное – значение. Термин предложили специалисты по теории вычислительных систем Джеральд Попек и Роберт Голдберг (1974). Изначально он означал “эффективный, изолированный дубликат реальной машины” – дубликат, состоящий из… инструкций. Реальная машина – назовем ее А – это настоящий аппарат, сконструированный из кремниевых чипов, проводов и тому подобного, а виртуальная машина – это компьютерная программа (выполняющаяся на другой реальной машине, машине Б), которая полностью имитирует аппаратное обеспечение машины А: она может работать немного медленнее, потому что ей приходится составлять все базовые операции машины А из базовых операций, доступных на ее собственном аппаратном обеспечении, машине Б, но при этом выполняет те же самые программы. Программа, написанная для выполнения на аппаратном обеспечении А, должна без проблем выполняться и на аппаратном обеспечении Б, если на аппаратном обеспечении Б работает виртуальная машина, имитирующая машину А.
Этот фокус удивительно полезен – и не только из-за явной экономии, которую он предполагает: скажем, у вас нет компьютера на Mac OS, но есть дорогое программное обеспечение, работающее только на Mac OS. В таком случае вы можете написать виртуальную машину (ВМ), имитирующую Mac OS на вашем компьютере на Windows, и тогда программы для Mac OS будут работать на вашем компьютере при запущенной ВМ Mac OS. Ваш компьютер на Windows будет “притворяться” компьютером на Mac OS, но программы ничего не поймут! Представьте человека, который сломал руку. Ему наложили гипс, который сильно ограничивает подвижность руки, а его вес и форма также требуют корректировки остальных движений тела. Теперь представьте мима (скажем, Марселя Марсо), который изображает человека с загипсованной рукой. Если мим хорош в своем деле, движения его тела будут ограничиваться ровно так же: у него на руке виртуальный гипс – и он “практически виден”. Компьютер на Windows, имитирующий компьютер на Mac OS с применением ВМ Mac OS, должен быть неотличим – для программного обеспечения, работающего на нем, и для стороннего наблюдателя – от настоящего компьютера на Mac OS.
В реальности все обычно наоборот. Хотя и есть сконструированные ВМ Mac OS, работающие на Windows, насколько мне известно, это скорее баловство, чем настоящее, практичное программное обеспечение. Напротив, для Mac OS созданы надежные, удобные в использовании ВМ Windows, которые позволяют владельцам компьютеров на Mac OS запускать любые программы, написанные для Windows. Большинство программ сегодня создается без привязки к конкретному аппаратному обеспечению, но с привязкой к конкретным операционным системам (которые, в свою очередь, работают на разном аппаратном обеспечении). Первая причина расширить определение виртуальной машины – необходимость включить в него виртуальные имитации операционных систем. Операционная система тоже представляет собой своеобразную виртуальную машину, позволяя немного разному аппаратному обеспечению выполнять одни и те же программы, но операционная система – это исключительно программное обеспечение; она не имитирует настоящее аппаратное обеспечение, но создает – фактически задавая конкретные условия – воображаемую машину, которая подчиняется определенным правилам, принимает определенные данные и так далее.
Другая причина расширить определение заключается в том, что одной из самых популярных и широко распространенных виртуальных машин сегодня является виртуальная машина Java, или JVM, которая, подобно операционной системе, не имитирует никакую аппаратно-реализованную машину, а существует только в форме программно-реализованной машины. Именно изобретению Java интернет в основном обязан своей универсальностью: Java позволяет скачивать с сайтов маленькие программы – Java-апплеты, – которые дают возможность разгадывать кроссворды, играть в судоку, изучать карты, увеличивать фотографии, играть в игры с людьми с другого конца света, а также решать множество “серьезных” вычислительных задач. Создавая программы на языке программировании Java, веб-дизайнер не должен знать, кто именно придет к нему на сайт – пользователи Mac OS, Windows (или Linux), – поскольку Java-апплет всегда запускается на JVM, сконструированной специально для работы на компьютере на Mac OS, Windows или Linux. Соответствующая JVM автоматически скачивается и за несколько секунд устанавливается на ваш компьютер, а затем Java-апплет, как по волшебству, выполняется на этой JVM. (Возможно, вы замечаете, как на ваш компьютер скачиваются обновления Java, а возможно, и не замечаете этого! В идеале вы можете забыть о том, какая JVM установлена у вас на компьютере, и ожидать, что каждый посещаемый вами сайт либо будет использовать Java-апплеты, которые уже работают на вашей JVM, либо соответствующим образом обновит Java для корректной работы.)
Таким образом, в соответствии с моим расширенным определением термина, виртуальной машиной можно считать практически любую компьютерную программу, поскольку она представляет собой программное обеспечение – систематический список инструкций, – при запуске превращающее универсальный компьютер в машину конкретного назначения, которую можно было бы сконструировать и подключить в качестве аппаратного обеспечения. Алан Тьюринг сделал блестящий вклад в науку – и оказал огромную услугу человеческой цивилизации второй половины двадцатого века, – предложив идею “универсального” компьютера (сегодня мы называем его универсальной машиной Тьюринга), который можно превратить в любой другой компьютер, созданный для конкретной цели, просто установив и запустив соответствующую программу! (Если вы решили пропустить главу 24, то имейте в виду: в ней об этом говорится подробнее.) Не нужно создавать все возможные конфигурации аппаратного обеспечения – хватит и одной, ведь все остальное сделает программное обеспечение. Со времен Тьюринга нам известно, что можно взять сложную штуковину – аппаратное обеспечение, – обладающую большой пластичностью – регулируемыми ячейками “памяти” или регистрами, – и поместить в эти ячейки памяти набор инструкций, при выполнении которых эта штуковина превратится в любой компьютер, какой нам под силу ясно вообразить.
Машина Тьюринга – или ноутбук – выполняет по одной инструкции зараз и переходит к следующей инструкции, но “параллельные” компьютеры могут выполнять много (миллионов) инструкций одновременно. Регистр – это любой фрагмент аппаратного обеспечения, который может пребывать в том или ином состоянии (например, в состоянии нуля или единицы в случае с компьютерными битами, но состояний может быть и больше двух), пока не получит команду изменить состояние. Любая система регистров, которая может производить определенные элементарные операции на основании этих состояний (к примеру, менять состояние регистра или использовать состояние регистра, чтобы определить, какую операцию выполнять дальше), может и настраивать свои регистры таким образом, чтобы “вычислить функцию” или “исполнить программу”. Получается, что на любом подобном аппаратном обеспечении может работать виртуальная машина, созданная для использования этих простых шагов. Этот фокус можно проворачивать не один, а много раз, устанавливая виртуальные машины на виртуальные машины на виртуальных машинах… на аппаратном обеспечении.