简体   繁体   English

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

[英]What's the difference between the inner workings of Java's JVM and .NET's CLR?

What's the difference between the inner workings of Java's JVM and .NET's CLR? Java的JVM和.NET的CLR的内部工作有什么区别?

Perhaps a starting point would be, are they basically the same thing in their respective environments (Java > JVM > Machine code) (C# > CLR > IL). 也许是一个起点,它们在各自的环境中基本相同(Java> JVM>机器代码)(C#> CLR> IL)。


Update: Several people have alluded to the points I was trying to cover: 更新:有几个人提到我试图涵盖的要点:

  1. Garbage Collection 垃圾收集
  2. Boxing/Unboxing 装箱/拆箱
  3. JIT debugging JIT调试
  4. Generics/Templates 泛型/模板
  5. Please feel free to suggest other good topics that differentiate the two. 请随意提出其他可以区分两者的好主题。

@George Mauer - this sounds very interesting: @George Mauer - 听起来很有趣:

Already posted this once but here is a series of interviews with c# chief language designer Anders Hejlsberg. 已经发布了一次,但这里是对c#首席语言设计师Anders Hejlsberg的一系列采访

This should be a great thread. 这应该是一个很好的主题。

One of the biggest differences is between the CLR and JVM is the CLR"s native integration of generics. CLR和JVM之间最大的区别之一是CLR与泛型的本机集成。

Java instead removes the generic types and the JVM can only work with objects by autoboxing the objects it appears to be pseudo generics. 相反,Java会删除泛型类型,而JVM只能通过自动装箱看似伪随机的对象来处理对象。

From here . 这里开始 I couldn't have said it better (Well, with the exception of a flame war, this is a flameless place :-) ). 我不能说得更好(嗯,除了火焰战争,这是一个无焰的地方:-))。

Hello, 你好,

Responding to your question seems fraught with peril by starting a flame war, so I'll proceed cautiously. 通过启动火焰战来回应你的问题似乎充满了危险,所以我会谨慎行事。

There are a number of fundamental technical similarities between the Java Runtime and the Common Language Runtime, including garbage collected memory, an intermediate language (Microsoft IL versus Java ByteCode), core system libraries, and support for fairly high level languages, code security, and deployment. Java Runtime和公共语言运行时之间存在许多基本的技术相似之处,包括垃圾收集内存,中间语言(Microsoft IL与Java ByteCode),核心系统库以及对相当高级语言的支持,代码安全性以及部署。

However, each of these 'similar' areas also have a number of sizable and small differences, and it's beyond the scope of a simple Forum post to describe most of them. 然而,这些“相似”区域中的每一个也存在许多相当大的差异,并且超出简单论坛帖子的范围来描述它们中的大多数。

I would suggest asking a more targetted question about any of the various runtime features and component areas (eg memory management, compilation, system libraries, security, etc.) and then we can provide a more targetted response (eg a blog, a technical article, or some books). 我建议询问有关各种运行时功能和组件区域(例如内存管理,编译,系统库,安全性等)的更具针对性的问题,然后我们可以提供更具针对性的响应(例如博客,技术文章)或者一些书籍)。

The CLR and JVM have goals and philosophies that differ more than you might think. CLR和JVM的目标和理念不同于您的想法。 In general, the JVM aims to optimize more dynamic, higher-level code while the CLR gives you more low-level tools to do these kinds of optimizations yourself. 通常,JVM旨在优化更动态,更高级别的代码,而CLR为您提供更多低级工具来自行执行这些类型的优化。

A good example is stack allocation. 一个很好的例子是堆栈分配。 On the CLR you have explicit stack allocation of custom value types. 在CLR上,您可以显式定义自定义值类型的堆栈。 On the JVM the only custom types are reference types but the JVM can convert heap allocations to stack allocations in certain circumstances through Escape Analysis. 在JVM上,唯一的自定义类型是引用类型,但JVM可以通过Escape Analysis在特定情况下将堆分配转换为堆栈分配。

Another example. 另一个例子。 In Java, methods are virtual by default. 在Java中,默认情况下方法是虚拟的。 On C# at least, they are not. 至少在C#上,它们不是。 It is much more difficult to optimize virtual method calls because the code that gets executed at a given call site cannot be determined statically. 优化虚方法调用要困难得多,因为无法静态确定在给定调用站点执行的代码。

Under the hood, their execution systems are quite different. 在引擎盖下,他们的执行系统是完全不同的。 Most JVMs (in particular, Hotspot) start out with a bytecode interpreter and only JIT-compile parts of the code that are executed heavily eg tight loops. 大多数JVM(特别是Hotspot)从一个字节码解释器开始,只有JIT编译的代码部分被大量执行,例如紧密循环。 They can also re-compile these over and over each time using execution statistics collected from previous runs to drive optimizations. 他们还可以使用从先前运行中收集的执行统计信息一次又一次地重新编译这些以驱动优化。 This allows more optimization effort to be applied to the parts of the program that need it most. 这允许将更多优化工作应用于最需要它的程序部分。 This is called adaptive optimization. 这称为自适应优化。

The CLR compiles everything up-front only once. CLR只预编译一次。 It does fewer optimization both because it has more code to compile and so has to be fast and because it doesn't have any statistics of the actual execution paths taken to feed into its optimizations. 它的优化次数较少,因为它有更多的代码需要编译,因此必须快速,因为它没有任何实际执行路径的统计信息来提供给它的优化。 This approach does have the very significant advantage of allowing you to cache compilation results across processes, which CLR does but JVM does not. 这种方法确实具有非常显着的优势,允许您跨进程缓存编译结果,CLR会这样做但JVM却没有。

A large percentage of the Hotspot JVM code is dedicated to these adaptive optimizations and they are what put Java in the same performance ballpark as native code for most general purpose computation in the early 2000s. 大部分Hotspot JVM代码专用于这些自适应优化,它们使Java与21世纪初大多数通用计算的本机代码处于相同的性能范围。 They are also what makes the JVM a decent target for dynamic languages. 它们也是使JVM成为动态语言的理想目标的原因。 I'm excluding here the more recent developments of the Dynamic Languages Runtime and invokedynamic as I don't know enough about the DLR. 我在这里排除了动态语言运行时和invokedynamic的最新发展,因为我对DLR知之甚少。

One essential difference is that the JVM is portable across platforms and runs on Linux, Macintosh, and many cell phones and embedded devices. 一个重要区别是JVM可跨平台移植,可在Linux,Macintosh以及许多手机和嵌入式设备上运行。

CLR runs on Microsoft supported platforms with the Mono project providing partial support of older versions of CLR on a few more. CLR在Microsoft支持的平台上运行,Mono项目提供了对旧版CLR的部分支持。

Internally this means the JVM's performance will vary on those different platforms based on capabilities provided by the platforms themselves. 在内部,这意味着JVM的性能将根据平台本身提供的功能在这些不同的平台上发生变化。

Miguel de Icaza mentions here : Miguel de Icaza 在这里提到:

Seasoned industry programmers will notice that the above is very much like Java and the Java VM. 经验丰富的行业程序员会注意到上面的内容与Java和Java VM非常相似。 They are right, the above is just like Java. 他们是对的,上面就像Java一样。

The CIL has one feature not found in Java though: it is byte code representation that is powerful enough to be used as a target for many languages: from C++, C, Fortran and Eiffel to Lisp and Haskell including things like Java, C#, JavaScript and Visual Basic in the mix. CIL有一个在Java中找不到的功能:它是字节代码表示,功能强大,足以用作许多语言的目标:从C ++,C,Fortran和Eiffel到Lisp和Haskell,包括Java,C#,JavaScript等和Visual Basic混合使用。

I wish I had the time to go in more detail, but for the sake of this argument, the above will suffice. 我希望我有时间更详细,但为了这个论点,上述内容就足够了。

The comments go into some details, though, like tail call optimizations. 但是,评论会进入一些细节,例如尾部调用优化。 Lot have changed since 2002 though - both CLR and JVM now have multiple languages targeting it. 自2002年以来,Lot已发生变化 - CLR和JVM现在都有多种语言针对它。 But nonetheless worth a read. 但值得一读。

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

As Vinko said, the full details are way beyond the scope of a forum post. 正如Vinko所说,完整的细节超出了论坛帖子的范围。 The differences/similarities boil down to this: 差异/相似之处归结为:

They are both a runtime environment "sandbox" that include a "just-in-time" compiler to translate program instructions in an intermediate language (MSIL or ByteCode) to native machine code and provide automatic memory management (garbage collection). 它们都是运行时环境“沙箱”,包括“即时”编译器,用于将中间语言(MSIL或ByteCode)中的程序指令转换为本机机器代码,并提供自动内存管理(垃圾收集)。 Sitting on top of the respective runtime environments are a set of class libraries that provide higher level abstractions to developers to simplify development tasks. 坐在相应运行时环境之上的是一组类库,它们为开发人员提供更高级别的抽象,以简化开发任务。

The internals of how those runtime environments are actually implemented are, for the most part, proprietary to Microsoft and Sun. 这些运行时环境实际实现的内部结构大部分是Microsoft和Sun专有的。 The algorithms used by the garbage collection systems, for example, while probably similar in technical functionality are different in implementation. 例如,垃圾收集系统使用的算法虽然在技术功能上可能类似,但在实现上是不同的。

There differences in garbage collection as well. 垃圾收集也存在差异。 JVM uses Copying collector and Mark and sweep. JVM使用复制收集器和标记和扫描。 .NET user Copying collector and Mark and compact (Much harder to implement). .NET用户复制收集器和Mark和compact(更难实现)。

Also type erasure mentioned by Flyswat is important. Flyswat提到的类型擦除也很重要。 JVM doesn't have a clue about generics and everything is object and associated perf. JVM没有关于泛型的线索,一切都是对象和相关的perf。 penalty of boxing and unboxing. 拳击和拆箱的惩罚。 Also reflection won't give you generic information. 反射也不会给你一般信息。 CLR supports generics natively. CLR原生支持泛型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM