托管代码与非托管代码的区别

6

我正在努力理解托管代码和非托管代码的概念。如果我错了,请纠正我,托管代码是被编译成字节码的任何内容,而非托管代码则被编译成机器码。

这样说对吗?


这都与垃圾回收有关,托管代码的独特之处在于GC可以找回代码使用的对象引用。即时编译器在此方案中发挥着非常关键的作用,除了将MSIL编译为机器码(就像C编译器处理C代码一样),它还生成一个表格,告诉GC在哪里查找对象引用。这个表格是区别所在,非托管代码无法提供该表格。 - Hans Passant
可能是什么是C#中的托管/非托管代码?的重复问题。 - T.Todua
1个回答

7

根据annakata的回答:

托管代码不会被编译成机器码,而是被编译为中间语言,由某个服务在计算机上解释和执行,并因此在一个(希望!)安全的框架内处理像内存和线程这样的危险事物。在现代应用中,这通常意味着.NET,但不一定。

非托管代码被编译成机器码,因此直接由操作系统执行。因此,它具有托管代码不具备的能够进行破坏性/强大操作的能力。这就是一切以前的工作方式,因此通常与.dll文件等旧东西相关联。

现在,在幕后发生了什么?托管与非托管都关乎于内存。

在托管代码中,代码本身并不直接操作内存。它向运行时提供指令,由其代表代码执行操作。这样,不安全或非法的操作可以被阻止,代码可以在半沙箱中运行。托管语言可以并且经常包含非托管代码-这是计算机的本质。

将内存想象成一个巨大的停车场。受控和不受控语言之间的区别如下:

在受控语言中,您走到停车场管理员那里,并解释需要停放10辆车。您不知道它们确切的停放位置,但是您知道管理员随时都可以为您取回。您也不能决定它们停在什么地方-您只能告诉停车管理员它们需要停放。

在非受控语言中,则由您来选择停车位。您可能会撞到其他车辆,停在残疾人停车位上,以及做出更多愚蠢/危险的错误。这为您提供了更好的性能(您无需不断向管理员传达指令),但您也可能犯下很多愚蠢/危险的错误。


难道没有一种编译成机器码的托管语言吗?我认为这个区别严格来说只是有无垃圾回收的区别。一个意味着另一个吗? - JamesFaix
如果它编译成机器码,那么唯一添加像垃圾收集器这样的特性的方法是在编译期间将大量汇编代码发出。也就是说,在将代码转换为汇编代码时,谚语中所说的“代客泊车员”几乎必须插入到每个其他代码行中。 - Athena
旧式LISP约简机如何呢?(并不是说你应该知道答案,或者这在今天真的重要吗。) - JamesFaix
你对楼主的回答很好,抱歉我有些跑题了。 - JamesFaix
@JamesFaix 我做了一些研究,你可能是对的。这似乎严重取决于编程语言。有时它会在运行时发生(Python、Java),有时它会在编译之后但在执行之前发生。不过,最终所有东西都必须转换为本地代码。 - Athena
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接