那么...
你会如何向一个非程序员描述托管代码(或Java字节码)和非托管/本机代码之间的区别?
托管代码 == "拥有一整套仆人、女佣、厨师和园丁来维护房子的豪宅"
非托管代码 == "我在大学里曾经居住过的地方"
想象一下你的桌子,如果你经常整理它,就有空间放置你实际正在工作的东西。如果你不整理,你就会用完空间。
这个空间相当于计算机资源,如RAM、硬盘等。
托管代码允许系统自动选择何时以及清理什么。非托管代码使这个过程变得“手动”-也就是说,程序员需要告诉系统何时以及清理什么。
我相信基本的解释是:
malloc
和free
)我对这里的讨论结果感到惊讶(其实并不是,但从修辞上说是)。让我补充一些内容,即使我已经晚了。
虚拟机(VM)和垃圾回收(GC)已经存在几十年,并且是两个独立的概念。存在着使用垃圾回收本地代码编译语言,甚至是几十年前的语言(经典例子: ANSI Common Lisp;还有至少一个 在编译时 进行垃圾回收 的声明性语言 Mercury - 但显然大众喜欢像 Prolog 的语言)。
Suddenly GCed基于字节码的虚拟机成为了解决所有IT问题的灵丹妙药。 现有二进制文件的沙盒化(其他例子在这里,在这里和在这里)? 最小权限原则(POLA)/基于能力的安全性? 精简二进制文件(或其现代变体SafeTSA)? 区域推断? 不,先生:微软和Sun甚至不允许我们考虑这样的扭曲行为。 不,最好为这种美妙(???)的新(???)语言§/API重新编写整个软件堆栈。 正如我们的一位主持人所说,这又是火与运动。§ 别傻了,我知道C#不是唯一一个针对.Net/Mono的语言,这是夸张之词。
编辑:阅读S.Lott对此答案的评论,以了解我指出的内存管理/安全性/代码可移植性的替代技术,这尤其具有教育意义。
我的观点是,非技术人员在这个细节层面上不需要被困扰。
另一方面,如果他们被微软/甲骨文的营销所吸引,有必要向他们解释,他们正在被愚弄——基于GC的字节码虚拟机并不像它们声称的那样新颖,它们不能神奇地解决每一个IT问题,而且存在其他实现技术的替代方案(有些更好)。
编辑2: 垃圾回收是一种内存管理技术,和每种实现技术一样,需要被理解才能正确使用。看看在ITA Software中,他们是如何绕过GC以获得良好的性能:
4 - 由于我们拥有约2GB的静态数据需要快速访问,因此我们使用C++代码将包含指针为空的C结构(例如航班、票价等)的巨大文件映射到内存中,然后使用外部数据访问从Common Lisp中访问这些数据。一个结构体字段访问会编译为两到三个指令,因此使用C而不是Lisp对象访问实际上没有性能损失。通过这样做,我们可以使Lisp垃圾回收器无法看到数据(对于Lisp来说,指向C对象的每个指针只是一个fixnum,虽然我们经常会暂时将这些指针包装在Lisp对象中以提高可调试性)。因此,我们的Lisp镜像只包含约250MB的“工作”数据结构和代码。这是我的答案:
使用托管 (.NET) 或字节码 (Java) 可以为您节省时间和金钱。
现在让我们比较一下两者:
非托管或本机代码
您需要自己进行资源 (RAM / 内存) 分配和清理。如果您忘记了某些内容,就会出现所谓的“内存泄漏”,导致计算机崩溃。内存泄漏是一个术语,用于描述应用程序开始使用(消耗)Ram/内存,但不释放它,因此计算机无法将其用于其他应用程序;最终导致计算机崩溃。
为了在不同的操作系统上运行您的应用程序(如Mac OSX、Windows等),您需要为每个操作系统编译您的代码,并可能更改很多特定于操作系统的代码,以便在每个操作系统上正常工作。
.NET 托管代码或 Java 字节码
所有资源(RAM / 内存)分配和清理都由系统完成,创建“内存泄漏”的风险降至最低。这使得更多的时间可以用于编写功能,而不是花费在资源管理上。
为了在不同的操作系统(如Mac OSX、Windows等)上运行您的应用程序,您只需编译一次,只要它们支持您的应用程序所依赖的框架(.NET Framework/Mono或Java),它就可以在每个操作系统上运行。非托管代码是计算机要遵循的指令列表。 托管代码是计算机要遵循的任务列表,计算机可以自由解释如何完成这些任务。
最大的区别在于内存管理。使用本地代码,您必须自己管理内存。这可能很困难,并且是许多错误和大量开发时间用于跟踪这些错误的原因。使用托管代码,您仍然会遇到问题,但问题较少且更容易跟踪。这通常意味着软件错误较少,开发时间也较短。
还有其他区别,但内存管理可能是最大的区别。
如果他们仍然感兴趣,我可能会提到许多漏洞都来自缓冲区溢出,而使用托管代码则不会出现这种情况,或者现在可以轻松重用代码,或者我们不再需要处理COM(如果你很幸运的话)。否则,我可能会远离COM,否则我会对它的糟糕之处进行抨击。
“托管代码”这个特定术语在微软世界中非常普遍。
由于我工作在MacOS和Linux的世界中,这不是我使用或遇到的术语。
Brad Abrams的博客文章 "What is Managed Code" 给出了一个定义,例如“.NET Framework Common Language Runtime”。
我的观点是:可能根本不必解释这个术语。如果它是一个错误、黑客或解决方法,那么它并不是非常重要。当然,没有必要为此制作一个复杂的通俗描述。它可能会随着下一批微软产品的发布而消失。