托管语言与编译语言的区别?


18

当人们试图区分编译语言和托管语言时,我感到困惑。从经验中,我了解到大多数人认为编译语言是C,C ++,而托管语言是Java,C#(显然还有更多,但这些只是少数示例)。但是,两种语言之间的核心区别到底是什么?

我的理解是,无论您使用哪种语言,任何程序本质上都被“编译”为低级机器代码,然后对其进行解释,这也使得托管语言成为编译语言的子集(也就是说,所有托管语言都是编译语言,但不是相反)吗?


2
这个术语是由Microsoft创造的,从狭义上讲,Java也被管理。几乎在所有情况下,我们都可以想到托管语言,例如编译语言的子集。此外,我认为这是相关的- 程序员
.stackexchange.com / questions / 72446 /…

请注意,一种语言(静态地)将代码编译为在运行时之前可管理的某种机器(如Java)与一种在运行时进行的机器(如Python)之间存在巨大差异。一个主要的区别是,在运行时之前对其进行静态编译使编译器有机会进行一些优化,从而可能会极大提高速度(例如Java的JIT,重新安排代码以进行分支预测等)。
Shivan Dragon 2012年

6
@ShivanDragon,“语言”不会编译任何内容。它的实现。而且,您可以静态地编译Python(例如,参见PyPy或IronPython)。OTOH,使用动态类型的语言(查找“跟踪JIT”,“抽象解释”等)来有效地做到这一点确实很难
SK-logic

@ SK-logic:同意,我说过一个坏蛋。我想指的是平台,而不是语言。
Shivan Dragon 2012年

@shabunc实际上我会说Compiled是Managed的子集。托管语言可以执行编译语言可以执行的任何操作(几乎以相同的速度),由于托管语言可以被编译,因此可以执行更多操作。为了使C具有托管语言的功能,您需要构建“ VM”并将其实际用作托管语言。
Bill K

Answers:


47

区别不是“编译”与“托管”,它们是两个正交轴。“受管理”通常表示存在垃圾收集的内存管理和/或存在虚拟机基础结构。两者绝对与编译无关,也与人们认为与编译相反的事情无关。

所有这些“差异”非常模糊,人为且无关紧要,因为始终可以在单个运行时中混合托管和非托管内存,并且编译和解释之间的差异也非常模糊。


2
这基本上就是我的初衷,但是我遇到了很多不断做出这种区分的人。感谢您的明确答复。
l46kok 2012年

托管代码意味着拥有一种中间语言来照顾您在运行时正在运行的任何执行环境,对吗?因此,中间语言(比如说字节码)必须由编译器生成。IMO,这将“托管”代码和“编译”概念稍加耦合。但是,如果语言是“编译的”,则不能表示它会生成托管代码(即C ++与Java)
zgulser

@zgulser,不,中间语言是正交的。托管意味着将GC与语言运行时集成在一起。例如,OCaml运行时是“托管”的,尽管它可以直接编译为本机。
SK-logic

8

引用维基百科:

托管代码是Microsoft创造的一个术语,用于标识需要且仅在公共语言运行时虚拟机(导致字节码)管理下执行的计算机程序源代码。

托管代码需要运行时(例如.NET CLT)才能执行。


5
托管代码与框架无关。它需要一个运行时来管理内存。
Oded 2012年

也许我的措辞有些偏离,但是.NET框架实际上不是“公共语言运行时”吗?
janvdl 2012年

3
不。In包括CLR,但还包括基类库,IL规范等。
2012年

4

我认为有区别,但是“已编译”和“受管理”之间不一定有区别。这些不是对立的。语言可以被编译和不被管理,或者可以被解释(不被编译)和被管理,或两者兼而有之。

“编译”语言只是其中的一种,其中有一个步骤将开发人员编写的源代码转换为某种更常规的“字节码”,即由机器执行的字节码。“机器”可以是实际的处理器,也可以是对字节码执行附加操作以将其转换为“本机”机器指令的“虚拟机”。“编译”语言的反义词是“解释”语言,其中在运行时将源代码在执行时逐行转换为字节码指令,而无需编译步骤。它们之间的混合是“ JIT”(Just In Time)中的“ jitting”,它通常被执行机器解释为一次性步骤;

“托管”语言是一种设计用于生成在特定运行时环境中使用的程序的语言,该运行时环境几乎总是包含字节码解释器;一个“虚拟机”,它采用程序的代码并执行一些其他机器或特定于环境的转换。该环境还可以包括内存管理,例如“垃圾收集器”和其他“安全”功能,这些功能旨在使程序在其空间和工具的“沙箱”中运行,但是这些功能并非“托管”运行时的唯一领域。实际上,所有解释语言都可以视为托管语言,因为它们要求解释器在要执行的“用户”代码行下运行。此外,JVM和.NET语言(Java,Scala,C#,VB,F#,IronWhatever)被编译成一种中间语言或IL,其形式和功能与二进制汇编语言在表面上相似,但并不100%遵循任何“本机”指令集。这些指令由JVM或.NET的CLR执行,它们将它们有效地转换为特定于计算机CPU体系结构和/或操作系统的本机二进制指令。

因此,语言通常可以描述为“编译”或“解释”,以及“非托管”(或“本机”)和“托管”。可以将这些语言描述为这些语言的任何组合,除了可能的“解释的本机”(仅适用于手写十六进制操作码(开发人员写的是执行的东西)才适用);如果您将解释层视为“运行时”(这很容易辩驳,很难反对),则所有解释语言都是“托管”的。

如果您想获得技术知识,那么如今几乎所有针对多任务OS的程序都是“托管”的;操作系统将为每个正在运行的程序创建一个“虚拟机”,在该程序中,程序认为(或至少不必知道其他情况)它是唯一正在运行的程序。该代码可以在其内部进行调用,也可以对其他引用的库进行调用,就好像该程序是内存中唯一加载的程序一样。类似地,分配RAM和其他更高内存以存储和操作数据以及控制设备的调用被编码为好像整个内存体系结构都可用。然后,VM(及其背后的OS)将各种内存指针转换为程序的实际位置,其数据以及与设备驱动程序的挂钩等。这通常是通过应用内存偏移量来完成的(每个VM获得2GB的块)或任何记忆 从地址X开始,程序可以将其视为好像X是地址0),并且这样做非常便宜,但是OS内核还负责其他事情,例如进程调度和进程间通信。棘手的管理。但是,通常不将这种基本模式视为“托管”模式,因为该程序不必知道它是由虚拟机运行的,并且通常仍负责保持其分配的内存“干净”。专为在MS-DOS命令行上运行而设计的程序可以在甚至不再具有MS-DOS环境的新型Windows操作系统上运行。相反,该程序被赋予了“虚拟控制台”环境,并且前提是它不尝试离开此“沙盒”


“语言通常可以描述为“编译”或“解释”” –不,它们不能。编译和解释是编译器和解释器的特性,而不是语言的特性。术语“编译语言”甚至没有意义。如果英语是一种打字语言,那将是一种打字错误。
约尔格W¯¯米塔格

2
通常发现编译器和解释器可以编译和解释非常特殊的语言方言,这些方言旨在进行编译或解释。没有人知道我正在编译的JavaScript源代码,也没有人解释C#。语言被设计为以一种或另一种方式使用。这样,将语言本身称为“已编译”或“解释” 通常是可以接受的,因为在其中使用该语言的完整环境涉及这两个步骤之一。
KeithS 2012年


en.wikipedia.org/wiki/Interpreted_language- “从理论上讲,任何语言都可以编译或解释,因此使用此名称纯粹是出于常见的实现实践,而不是某种语言的某些基本属性。”
KeithS 2012年

@KeithS,维基百科并不完美。文章中存在某个无效术语的事实并不能使该术语更有效。是的,语言在设计时始终会考虑特定的执行方式,但是仅根据设计者的意图对它们进行“编译”或“解释”商标仍会适得其反。而且,对于解释而言,真的很难以任何方式找到合适的“解释器”。Tcl可能是同类产品中的最后一个。所有其他所谓的“解释器”实际上是编译器。
SK-logic

2

简单来说,托管语言是一种高级语言,它依赖于运行时环境提供的服务来执行,例如垃圾收集服务,这就是为什么将其一般称为托管的原因,但这并不是它使用的唯一服务和一些服务是security services, exception handling, standard types,它使用Common Language Run-time CLR来执行,像网络语言或Java等虚拟环境是用`Java虚拟机JVM。

非托管语言是可以直接由操作系统执行的低级语言,不需要虚拟运行时服务或中间语言,此类语言C, C++生成的非托管代码(例如非托管代码)之类的语言使用库例程,该例程可动态链接至OS以获取要执行的代码称为DLL(动态链接库),非托管代码直接访问内存,这就是为什么它比托管代码更快的原因,但是除非您要构建硬件驱动程序或复杂的视频游戏,否则您实际上并不想使用非托管语言作为与角色状态(如角色状态)缺乏经验的开发人员一起工作可能会很危险with great power comes great responsibility,这就是为什么存在托管语言可以帮助开发人员生成可扩展代码而无需深入系统底部的原因,但是仍然可以根据需要创建混合代码,这些文章都对它们进行了解释:

托管/非托管代码互操作性概述

示例:混合非托管C ++,C ++ / CLI和C#代码

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.