Управляемые языки и скомпилированные Языковые различия?

18

Я запутываюсь, когда люди пытаются провести различие между компилируемыми языками и управляемыми языками. По своему опыту я понимаю, что большинство считает компилируемые языки C, C ++, а управляемые языки - Java, C # (очевидно, их больше, но это лишь несколько примеров). Но что именно является основным различием между двумя типами языков?

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

l46kok
источник
2
этот термин придуман Microsoft, в узком смысле и Java управляется. Почти во всех случаях мы можем думать об управляемых языках, таких как подмножество того, который компилируется. Кроме того, это, я считаю, связано - programmers.stackexchange.com/questions/72446/…
shabunc
Обратите внимание, что существует огромная разница между языком, который компилирует (статически) код в нечто более управляемое компьютером до выполнения (например, Java), и языком, который делает это во время выполнения (например, Python). Одно из основных отличий состоит в том, что статическая компиляция перед выполнением дает компилятору возможность внести некоторые оптимизации, которые могут привести к значительным улучшениям скорости (например, JIT в Java, реорганизация кода для прогнозирования ветвлений и т. Д.).
Шиван Дракон
6
@ShivanDragon, «язык» ничего не компилирует. Его реализация делает. И вы можете компилировать Python статически (см., Например, PyPy или IronPython). ОТО, действительно трудно сделать это эффективно с динамически типизированным языком (посмотрите «отслеживание JIT», «абстрактная интерпретация» и т. Д.)
SK-logic
@ SK-логика: согласен, я сказал злодей. Я хотел сослаться на платформу, а не на язык.
Shivan Dragon
@shabunc На самом деле я бы сказал, что Compiled - это подмножество Managed. Управляемый язык может делать все, что может делать скомпилированный язык (практически с той же скоростью), и даже больше, поскольку управляемый язык может быть скомпилирован. Чтобы дать C возможности управляемого языка, вам нужно создать «виртуальную машину» и фактически сделать ее управляемым языком.
Билл К

Ответы:

47

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

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

SK-логика
источник
2
Это то, что я в основном имел в виду, но я встречал много людей, которые продолжают делать это различие. Спасибо за четкий ответ.
l46kok
Управляемый код означает наличие промежуточного языка, который должен заботиться о любой среде исполнения, в которой вы работаете во время выполнения, не так ли? Таким образом, этот промежуточный язык (скажем, байт-код) должен быть создан компилятором. ИМО, это немного объединяет «управляемый» код и концепцию «компиляции». Однако, если язык «скомпилирован», это не показывает, что он приводит к управляемому коду (т.е. C ++ против Java)
zgulser
@zgulser, нет, промежуточные языки ортогональны. Управляемый означает, что GC интегрирован с языковой средой исполнения. Например, среда выполнения OCaml "управляемая", хотя она компилируется прямо в нативную.
SK-logic
8

Цитировать Википедию:

Управляемый код - это термин, придуманный Microsoft для обозначения исходного кода компьютерной программы, который требует и будет выполняться только под управлением виртуальной машины Common Language Runtime (в результате получается байт-код).

Управляемый код требует выполнения (например, .NET CLT) для выполнения.

janvdl
источник
5
Управляемый код не имеет ничего общего с фреймворком. Это требует времени выполнения, которое управляет памятью.
Одед
Возможно, моя формулировка немного ошибочна, но разве .NET Framework не является "общеязыковой средой исполнения"?
Janvdl
3
Нет. In включает CLR, но также включает библиотеки базовых классов, спецификацию IL и многое другое.
Одед
4

Я думаю, что необходимо проводить различие, однако оно не обязательно должно быть «компилируемым» и «управляемым». Это не противоположности; язык может быть скомпилирован и не управляться, или интерпретироваться (не компилироваться) и управляться, либо и тем, и другим, или даже без него.

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

«Управляемый» язык - это язык, предназначенный для создания программ, которые используются в определенной среде выполнения, которая почти всегда включает интерпретатор байт-кода; «Виртуальная машина», которая принимает код программы и выполняет дополнительное преобразование для конкретной машины или среды. Среда может также включать управление памятью, такое как «сборщик мусора» и другие функции «безопасности», предназначенные для поддержания работы программы в «песочнице» пространства и инструментов, однако такие функции не являются единственной областью «управляемых» сред выполнения , Практически все интерпретируемые языки можно считать управляемыми, потому что они требуют, чтобы интерпретатор работал под строками исполняемого «пользовательского» кода. Кроме того, языки JVM и .NET (Java, Scala, C #, VB, F #, IronWhothing) компилируются в промежуточный язык или IL, которые внешне похожи по форме и функциям на бинарный язык ассемблера, но не придерживаются 100% любого «нативного» набора команд. Эти инструкции выполняются JVM или CLR .NET, что эффективно переводит их в собственные двоичные инструкции, специфичные для архитектуры ЦП и / или ОС компьютера.

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

Если вы хотите получить техническую поддержку, почти все программы, ориентированные на многозадачность ОС, в настоящее время являются «управляемыми»; ОС создаст «виртуальную машину» для каждой работающей программы, в которой программа думает (или, по крайней мере, не должна знать иначе), что это единственная работающая программа. Код может выполнять вызовы внутри себя и других библиотек, на которые ссылаются, как если бы эта программа была единственной вещью, загруженной в память; аналогично, запросы на выделение ОЗУ и другой более высокой памяти для хранения и управления данными и управляющими устройствами кодируются так, как если бы была доступна вся архитектура памяти. Затем виртуальная машина (и операционная система за ней) преобразует различные указатели памяти в фактическое местоположение программы, ее данные и привязки к драйверам устройств и т. Д. Это чаще всего делается путем применения смещения памяти (каждая виртуальная машина получает блок по 2 ГБ). или что угодно из памяти, начиная с адреса X, который программа может обрабатывать так, как если бы этот X был адресом 0), и поэтому делать это очень дешево, но есть и другие вещи, за которые отвечает ядро ​​ОС, такие как планирование процессов и взаимодействие между процессами, которые сложнее управлять. Однако этот базовый шаблон, как правило, не считается «управляемым», поскольку программе не нужно знать, что она запускается виртуальной машиной, и часто по-прежнему отвечает за поддержание своей выделенной памяти «чистой». Программа, которая была разработана для запуска в командной строке MS-DOS, может быть запущена на более новых ОС Windows, в которых даже нет среды MS-DOS; вместо этого программе предоставляется среда «виртуальной консоли», и при условии, что она не пытается покинуть эту «песочницу»

Keiths
источник
«языки обычно можно описать как« скомпилированные »или« интерпретированные »» - нет, они не могут. Компиляция и интерпретация - это черты компиляторов и интерпретаторов, а не языков. Термин «скомпилированный язык» даже не имеет смысла. Если бы английский был типизированным языком, это была бы ошибка типа.
Jörg W Mittag
2
Компиляторы и интерпретаторы, как правило, компилируют и интерпретируют очень специфические диалекты языков, предназначенные для компиляции или интерпретации. Никто не компилирует исходный код JavaScript, о котором я знаю, и никто не интерпретирует C #. Языки предназначены для употребления так или иначе. По существу, обычно допустимо называть сам язык «скомпилированным» или «интерпретированным», поскольку полная среда, в которой используется язык, включает в себя один из этих двух этапов.
KeithS
en.wikipedia.org/wiki/Interpreted_language - «Теоретически любой язык может быть скомпилирован или интерпретирован, поэтому это обозначение применяется исключительно из-за общей практики реализации, а не из-за какого-либо существенного свойства языка».
KeithS
@KeithS, Википедия не почти идеальна. Тот факт, что статья существует для определенного недействительного термина, не делает этот термин более действительным. Да, языки всегда разрабатываются с учетом определенного способа исполнения, но все равно контрпродуктивно маркировать их «скомпилированными» или «интерпретированными» исключительно на основе их намерений дизайнеров. И что касается интерпретации, действительно трудно найти подходящего «переводчика» в любом случае. Tcl, вероятно, последний в своем роде. Все остальные так называемые «интерпретаторы» на самом деле являются компиляторами.
SK-logic
2

Управляемый язык в простых терминах - это язык высокого уровня, который зависит от сервисов, предоставляемых исполняемой средой, таких как сервис сбора мусора, поэтому он называется в общем управляемым, но это не единственный сервис, который он использует. и некоторые из этих служб security services, exception handling, standard typesиспользуются Common Language Run-time CLRдля выполнения, например, в языках .Net или в виртуальной среде, такой как Java, в которой используется Java Virtual Machine JVM.

Неуправляемый язык - это низкоуровневый язык, исполняемый непосредственно операционной системой без необходимости использования виртуальных служб времени выполнения или промежуточного языка. Такие языки, как C, C++неуправляемый код, создаваемый такими языками, используют библиотечные процедуры, которые динамически связаны с ОС, чтобы получить код для выполнения называется DLL (Dynamic Link Libraries), неуправляемый код обращается к памяти напрямую, поэтому он быстрее, чем управляемый код, но если вы не создаете аппаратный драйвер или сложную видеоигру, вы на самом деле не хотите использовать неуправляемые языки как работать с ним может быть опасно, особенно с неопытными разработчиками, такими как состояние ролиwith great power comes great responsibility , и именно поэтому существуют управляемые языки, которые помогают разработчикам создавать расширяемый код, не углубляясь в нижнюю часть системы, но, тем не менее, вы можете создавать смешанный код, если вам нужно, в следующих статьях объясняется все:

Обзор совместимости управляемого / неуправляемого кода

Пример: смешивание неуправляемого кода C ++, C ++ / CLI и C #

Ашраф Абусада
источник