我读过一本书,书中提到.net CLR是虚拟机?有人能为这件事辩解吗?在某些开发平台上,我们需要虚拟机概念的原因是什么?
如果没有完全面向对象的、功能像.net那样强大的虚拟机,难道不可能开发一个本机框架吗?
将CLR称为虚拟机的书是"Professional .Net Framework2.0“。
发布于 2009-10-26 14:19:01
这里有很多误解。如果您真的想要的话,我想您可以将.Net看作一个虚拟机,但是让我们看看.Net框架是如何真正处理您的代码的。典型的场景如下
。
这里有几个要点,但最重要的一点是,从来没有任何代码被解释过。相反,您可以在步骤5中看到它被编译成本机代码。这与将其加载到虚拟机中有很大的不同,原因如下:
完全编译的代码由cpu直接执行,而不是由额外的软件抽象层解释或翻译,这应该更快。JIT编译器denominator.
我想您可以把这称为虚拟机,从某种意义上说,JITter从开发人员那里抽象出真正机器的细节。就我个人而言,我认为这是不对的,因为对于许多人来说,虚拟机意味着一个运行时抽象,而不是针对.Net程序的本机代码。
与“虚拟机”环境不同的是,整个过程的另一个关键点是,它只是典型的过程。如果您真的愿意,您可以在发布之前预编译一个.Net程序集,并将本机代码直接部署到最终用户(提示:在整个程序的生命周期中,它的聚合速度较慢,因为您失去了特定于机器的优化)。当然,您仍然需要安装.Net运行时,但在这一点上,它与任何其他运行时API并没有太大的不同;它更像是一个具有良好API链接的集合dll,就像附带的VB或C运行时一样。这种方式将IL从图片中剔除,使得VM名称更难被证明是正确的。(我说的“有点”是因为IL仍然被部署并用于验证保存的代码,但它本身从未为执行而被触及)。
另一个值得注意的问题是缺乏VM进程。当您运行您的应用程序,没有普通的“沙箱”进程运行。与Java相比,如果在运行程序时打开任务管理器,您将看到一个专门针对Java的进程,而应用程序的实际进程是VM创建的沙箱中的一个线程。在.Net中,您可以直接在Windows任务管理器中看到应用程序的进程。
总之:您可以说IL + CLR + JIT以某种方式组成了一个虚拟机。我个人不这么认为,但如果你相信的话,我不会跟你争论。我想指出的是,当您告诉某人.Net运行在虚拟机中而没有进一步解释时,您与该人通信的想法是“在主机进程中解释字节码”。这是不对的。
更新--这个答案现在有点老了,事情变了,使得.Net更不像虚拟机。在容器时代,冷启动时间可能会影响更多,我的理解是,.Net核心的最新版本有更多的工具可以使部署本机代码(并在每次启动时跳过JIT步骤)变得更加容易。
发布于 2009-10-14 05:25:59
与类似,Java是一个解释虚拟机的字节码。
JVM解释包含java字节码的程序,而.net CLR解释包含微软所谓的“中间语言(IL)”指令的程序。这些字节码之间存在差异,但是虚拟机是相似的,并且希望提供类似的特性。
这两种虚拟机实现都能够将它们的输入字节码编译成它们正在运行的计算机的机器语言。这被称为“即时编译(JIT)”,生成的输出代码称为"JIT代码“。由于JIT代码包含计算机CPU的机器语言中的指令序列,这段代码有时被称为“本机”代码。
但是,JIT代码在质量和数量上与本机代码不同,如下所述。因此,本文认为JIT代码只不过是运行特定字节码程序时虚拟机的本机实现。
这两个虚拟机(VM)都渴望提供的一个特性是以防止某些危险编程错误的形式提供安全性。例如,这个网站论坛的标题,堆栈溢出,是由一种在本机代码中可能出现的危险错误所激发的。
为了提供安全和执行安全,VM在“虚拟机级别”实现了类型安全。分配给VM内存是为了存储存储在该内存位置中的数据类型。例如,如果一个整数被推到堆栈上,则不可能从堆栈中弹出一个双倍。C型“工会”是禁止的。禁止指针和直接访问内存。
如果结果是本地二进制文件(如EXE文件),那么对开发人员强制执行面向对象的语言框架就不能获得同样的好处。在这种情况下,我们将无法区分使用框架生成的本机二进制文件和使用框架以外来源的恶意用户生成的EXE。
在VM的情况下,类型安全在程序员允许访问的“最低级别”强制执行。(暂时忽略编写托管本机代码是可能的,也就是说。)因此,任何用户都不会遇到执行需要直接访问内存位置和指针的危险操作之一的应用程序。
实际上,.net CLR实现了一种编写本机代码的方法,这些代码可以被.net“托管”代码调用。在这种情况下,本机代码作者有责任不犯任何指针和内存错误。
当JVM和.net CLR都执行JIT编译时,这两个VM实际上都从提供的字节码中创建了一个本机编译的二进制文件。这个"JIT代码“比VM的解释器执行速度更快,因为即使JIT生成的机器语言代码也包含VM将要执行的所有VM所需的安全检查。因此,JIT输出代码不如通常不包含大量运行时检查的本机代码那么快。然而,这种速度性能的缺点被用来改善可靠性,包括安全性;特别是,防止使用未初始化的存储,强制执行赋值的类型安全,执行范围检查(从而防止基于堆栈和堆的缓冲区溢出),通过垃圾收集管理对象的生存期,动态分配是类型安全的。执行这种运行时行为检查的环境正在实现虚拟机的规范,只不过是虚拟机的机器语言实现。
发布于 2009-10-14 05:20:14
“虚拟机”部分是指将.NET代码编译成EXE和DLL作为“中间”汇编语言(IL)在虚拟机上运行,而不是实际的CPU汇编语言。然后,在运行时将ILM转换为实际的CPU程序集以供执行(称为实时编译或JIT编译)。
当然,您可以编写一个.NET编译器,以便将其编译为CPU汇编语言而不是IL。但是,这并不是对所有CPU都可移植的--您必须为每个OS/CPU对编译不同的版本。但是通过编译到ILM中,您可以让“虚拟机”处理CPU和OS特定的东西。
https://stackoverflow.com/questions/1564348
复制相似问题