19

Java 的 JVM 和 .NET 的 CLR 的内部工作方式有什么区别?

也许一个起点是,它们在各自的环境中是否基本相同(Java > JVM > 机器代码)(C# > CLR > IL)。


更新: 有几个人提到了我试图涵盖的要点:

  1. 垃圾收集
  2. 装箱/拆箱
  3. 即时调试
  4. 泛型/模板
  5. 请随意提出其他区分这两者的好主题。

@George Mauer - 这听起来很有趣:

已经发布过一次,但这里是对 c# 首席语言设计师 Anders Hejlsberg的一系列采访。

4

8 回答 8

9

这应该是一个很棒的线程。

CLR 和 JVM 之间最大的区别之一是 CLR 对泛型的本机集成。

相反,Java 删除了泛型类型,JVM 只能通过自动装箱对象来处理对象,它似乎是伪泛型。

于 2008-09-12T15:03:12.443 回答
6

这里。我不能说得更好(嗯,除了火焰战争,这是一个没有火焰的地方:-))。

你好,

回答你的问题似乎充满了发起火焰战争的危险,所以我会谨慎行事。

Java 运行时和公共语言运行时之间有许多基本的技术相似之处,包括垃圾收集内存、中间语言(Microsoft IL 与 Java ByteCode)、核心系统库以及对相当高级语言的支持、代码安全性和部署。

然而,这些“相似”领域中的每一个也有许多相当大和小的差异,并且超出了简单的论坛帖子的范围来描述其中的大部分。

我建议就各种运行时特性和组件领域(例如内存管理、编译、系统库、安全等)提出更有针对性的问题,然后我们可以提供更有针对性的回应(例如博客、技术文章,或一些书籍)。

于 2008-09-12T14:55:57.983 回答
2

One essential difference is that the JVM is portable across platforms and runs on Linux, Macintosh, and many cell phones and embedded devices.

CLR runs on Microsoft supported platforms with the Mono project providing partial support of older versions of CLR on a few more.

Internally this means the JVM's performance will vary on those different platforms based on capabilities provided by the platforms themselves.

于 2008-09-18T21:00:38.790 回答
2

CLR 和 JVM 的目标和理念比您想象的要大得多。一般来说,JVM 旨在优化更动态、更高级别的代码,而 CLR 为您提供更多低级工具来自己进行这些优化。

一个很好的例子是堆栈分配。在 CLR 上,您有自定义值类型的显式堆栈分配。在 JVM 上,唯一的自定义类型是引用类型,但 JVM 可以在某些情况下通过逃逸分析将堆分配转换为堆栈分配。

另一个例子。在 Java 中,方法默认是虚拟的。至少在 C# 上,它们不是。优化虚拟方法调用要困难得多,因为在给定调用站点执行的代码无法静态确定。

在引擎盖下,它们的执行系统完全不同。大多数 JVM(特别是 Hotspot)从字节码解释器开始,并且只对代码的执行量很大的部分进行 JIT 编译,例如紧密循环。他们还可以使用从以前的运行中收集的执行统计信息来一遍又一遍地重新编译这些数据,以推动优化。这允许将更多的优化工作应用于程序中最需要它的部分。这称为自适应优化。

CLR 只预先编译所有内容一次。它进行的优化较少,因为它有更多的代码要编译,因此必须要快,而且因为它没有任何实际执行路径的统计信息来进行优化。这种方法确实具有非常显着的优势,即允许您跨进程缓存编译结果,CLR 可以做到这一点,而 JVM 则没有。

很大一部分 Hotspot JVM 代码专门用于这些自适应优化,它们使 Java 在 2000 年代初期的大多数通用计算中处于与本机代码相同的性能范围内。它们也是使 JVM 成为动态语言的体面目标的原因。我在这里排除了动态语言运行时和invokedynamic 的最新发展,因为我对DLR 了解不够。

于 2013-04-07T11:47:05.337 回答
1

Miguel de Icaza在这里提到:

经验丰富的行业程序员会注意到,上述内容非常类似于 Java 和 Java VM。他们是对的,上面就像Java一样。

CIL 有一个 Java 所没有的特性:它是一种足够强大的字节码表示,可以用作许多语言的目标:从 C++、C、Fortran 和 Eiffel 到 Lisp 和 Haskell,包括 Java、C#、JavaScript和 Visual Basic 混合在一起。

我希望我有时间更详细地说,但为了这个论点,以上就足够了。

不过,评论涉及一些细节,例如尾调用优化。不过自 2002 年以来发生了很多变化——CLR 和 JVM 现在都有多种语言针对它。但仍然值得一读。

于 2008-09-12T16:14:03.037 回答
0

据我所知,.Net CLR 仍然在运行时内置了更加灵活和强大的代码访问安全性,允许更细粒度的权限和执行策略。

于 2009-12-17T03:14:34.740 回答
0

正如 Vinko 所说,完整的细节远远超出了论坛帖子的范围。差异/相似之处归结为:

它们都是运行时环境“沙盒”,包括“即时”编译器,用于将中间语言(MSIL 或字节码)的程序指令翻译成本地机器代码,并提供自动内存管理(垃圾收集)。位于各自运行时环境之上的是一组类库,它们为开发人员提供更高级别的抽象以简化开发任务。

这些运行时环境如何实际实现的内部机制在很大程度上是 Microsoft 和 Sun 专有的。例如,垃圾收集系统使用的算法虽然在技术功能上可能相似,但在实现上却不同。

于 2008-09-12T15:12:27.350 回答
-1

垃圾收集也存在差异。JVM 使用 Copying 收集器和标记和清除。.NET 用户复制收集器和标记和压缩(更难实现)。

Flyswat 提到的类型擦除也很重要。JVM 对泛型一无所知,一切都是对象和相关的性能。拳击和拆箱的惩罚。反射也不会为您提供一般信息。CLR 原生支持泛型。

于 2010-01-22T12:38:22.707 回答