作为对题为Differences between MSIL and Java bytecode?的问题的一种跟进,Java虚拟机与虚拟机的工作方式(主要)有什么不同或相似之处.NET Framework公共语言运行库(CLR)是否有效?

还有,.NET frameworkCLR是"虚拟机"还是没有虚拟机的属性?

推荐答案

两种实现之间有很多相似之处(在我看来:是的,它们都是"虚拟机").

首先,它们都是基于堆栈的虚拟机,没有"寄存器"的概念,就像我们在x86或PowerPC等现代CPU中看到的那样.所有表达式((1+1)/2)的求值是通过将操作数推到"堆栈"上,然后在指令(加法、除法等)需要使用这些操作数时将这些操作数从堆栈中弹出来执行的.每条指令都会将其结果推回到堆栈上.

这是实现虚拟机的一种方便方法,因为世界上几乎每个CPU都有一个堆栈,但寄存器的数量往往不同(有些寄存器是专用的,每条指令都希望其操作数位于不同的寄存器中,等等).

所以,如果你要对一台抽象机器建模,一个纯粹基于堆栈的模型是一个很好的方法.

当然,真正的机器不是这样运行的.因此,JIT编译器负责执行字节码操作的"注册",本质上是调度实际的CPU寄存器,以便尽可能包含操作数和结果.

所以,我认为这是CLR和JVM之间最大的共同点之一.

至于不同之处...

这两种实现之间一个有趣的区别是,CLR包含了创建泛型类型的指令,以及对这些类型应用参数化专门化的指令.因此,在运行时,CLR会考虑一个列表<;int>;与列表完全不同<;字符串>;.

在封面下,它对所有引用类型专门化使用相同的MSIL(因此列表<;字符串>;使用与列表<;对象>;相同的实现,在API边界处使用不同的类型强制转换),但每个值类型使用其自己的唯一实现(列表<;int>;生成与列表<;double>;完全不同的代码).

在Java中,泛型类型纯粹是一个编译器技巧.JVM不知道哪些类有类型参数,并且它不能在运行时执行参数专门化.

从实用的Angular 来看,这意味着您不能在泛型类型上重载Java方法.您不能有两个同名的不同方法,只是它们接受的是列表<;字符串>;还是列表<;日期>;.当然,因为CLR知道参数化类型,所以它可以毫不费力地处理泛型类型专门化上重载的方法.

在日常生活中,我注意到CLR和

其他重要区别包括:

  • CLR有闭包(作为C#委托实现).JVM仅在Java8之后才支持闭包.

  • CLR有协同程序(用C#‘yield’关键字实现).JVM没有.

  • CLR允许用户代码定义新值类型( struct ),而JVM提供固定的值类型集合(字节、短整型、整型、长整型、浮点型、双精度型、字符型、布尔型),并且只允许用户定义新的引用类型(类).

  • CLR支持声明和操作指针.这尤其有趣,因为JVM和CLR都采用严格的分代压缩垃圾收集器实现作为其内存管理策略.在一般情况下,严格压缩GC很难处理指针,因为当您将一个值从一个内存位置移动到另一个内存位置时,所有指针(以及指向指针的指针)都会失效.但是CLR提供了一种"固定"机制,这样开发人员就可以声明一个代码块,CLR不允许在其中移动某些指针.非常方便.

  • JVM中最大的代码单元可以是"包"(由"tected"关键字证明),也可以是JAR(即Java存档),因为它能够在类路径中指定JAR并将其视为代码文件夹.在CLR中,类被聚合到"程序集"中,CLR提供推理和操作程序集的逻辑(这些程序集被加载到"AppDomain"中,为内存分配和代码执行提供子应用程序级沙箱).

  • CLR字节码格式(由MSIL指令和元数据组成)的指令类型少于JVM.在JVM中,每个唯一的操作(添加两个int值、添加两个float值等)都有自己的唯一指令.在CLR中,所有MSIL指令都是多态的(添加两个值),JIT编译器负责确定操作数的类型并创建适当的机器代码.不过,我不知道哪种策略更可取.两者都有权衡.针对JVM的HotSpot JIT编译器可以使用更简单的代码生成机制(它不需要确定操作数类型,因为它们已经在指令中编码),但这意味着它需要更复杂的字节码格式和更多的指令类型.

我已经使用Java(并欣赏JVM)大约十年了.

但是,在我看来,CLR现在几乎在所有方面都是最好的实现.

.net相关问答推荐

从Couchbase删除_txn文档的推荐方法?""

使用 DataDog 收集 OpenTelemetry 跟踪

在 Invoke() 中运行时,跨线程操作对表单控件无效 - .NET

在 Inno Setup 中判断给定服务的依赖服务

双精度的 C++ 和 C# 十六进制值之间的差异

如何判断 IOException 是否为 Not-Enough-Disk-Space-Exception 类型?

将 BitmapImage 转换为 Bitmap,反之亦然

Int32.ToString() 是特定于文化的吗?

如何让 DateTimePicker 显示一个空字符串?

我应该默认推荐密封类吗?

我可以从 .NET/C# 获取其他进程的命令行参数吗?

使用 EPPlus 时如何设置列类型

实例化具有运行时确定类型的对象

如何在 C# 中创建 Word 文档?

有什么方法可以在不重新编译的情况下覆盖 .NET Windows 服务名称?

如何将 System.Type 转换为其可为空的版本?

如何将 WebResponse.GetResponseStream 返回转换为字符串?

C# - 你如何停止计时器?

无法使用 Unity 将依赖项注入 ASP.NET Web API 控制器

WinForms 中的模型视图演示者