【问题标题】:Why do we need/use managed code (over native)?为什么我们需要/使用托管代码(而不是原生代码)?
【发布时间】:2015-10-16 06:31:56
【问题描述】:

我在这里缺少一些基本的东西。从源语言编译成字节码 (java) 或中间语言 (.NET),然后从 JVM 或 CLR 内部运行它们有什么用?


使用托管代码会降低性能(无论是轻微还是大幅度),但有什么好处?我知道有垃圾收集和内存管理,但即便如此,直接将源代码编译为本机而不需要这个中间级别不是更好吗?

另外(我在这里添加它,因为它与问题直接相关) - 显然 Windows 10 通用应用程序是使用 .NET Native 编译的,它编译为本机机器代码。我很好奇为什么以前所有的 .NET 程序都没有这样做。

【问题讨论】:

  • 字节码的一大优势是无论您如何实现虚拟机都可以运行它。这在 Windows 中的范围是有限的,因为您实际上只针对少数架构(atom、x86 等)
  • .NET Native 并不是简单地“编译成机器码”,它本质上是提前 jit,所以以后不需要再 jit。这仍然会转换为与 jit 期间完全相同的机器代码;您对它的过分简化听起来就像您认为它神奇地变成了原生 c++。
  • @Krythic 我明白了。但这些不是我选择的词,我引用了我提到的链接 (.NET Native)。
  • Krythic 不正确。 .NET Native 编译器使用支持 Microsoft C++ 编译器的同一组技术。事实上,用于 .NET Native 的代码生成技术集几乎与为我们的非原生产品构建的 JIT 完全脱节。

标签: java c# jvm managed .net-native


【解决方案1】:

除了其他答案中指出的所有其他内容外,这种方法的主要好处是在开发和维护方面实现了重要的成本降低以及开发环境的可扩展性大大提高。

考虑没有中间语言的情况;您需要为每种支持的语言每个支持的平台开发和维护一个编译器。假设您有语言 L1L2L3 以及平台 P1P2P3。这意味着您需要开发和维护 9 种不同的编译器:C1(L1,P1), C2(L1, P2), C3(L1, P3)C4(L2, P1)

另一方面,拥有一种中间公共语言I可以让你开发3种语言特定的编译器C1(L1, I), C2(L2, I )C3(L3, I) 和 3 个特定于平台的编译器 C4(I, P1), C5(I, P2)C6(I, P3).

显然,您支持的语言和平台基础越大,成本降低就越显着。

它还为您在未来添加支持的平台或语言提供了很大的灵活性;任何一种新的语言L4 只需要开发一个编译器C(L4, I),并且您以一次开发的价格立即支持所有平台。相反,如果你有一个新平台P4,你只需要开发C(I, P4),宾果游戏,你就有L1L2L3 都在 P4 中工作。

这基本上是双赢的局面。

【讨论】:

    【解决方案2】:

    这是来自MSDN

    托管代码的好处

    托管语言提供了一种通用的方法来处理内存管理和垃圾收集的细节,但代价是少量的开销。这种权衡使您摆脱了容易出错的任务,并允许您编写更紧凑、更易读且无错误的程序。

    非托管代码的好处

    如果您使用非托管语言(例如 C++),则必须编写额外的代码来管理内存和安全性,并在对象达到其目的后对其进行清理。管家细节很复杂,与程序的预期功能无关,因此开发人员经常忽略这些任务,忽略它们,或者忘记它们。因此,非托管代码的测试成本和时间往往更高,并且需要更多的程序员培训和纪律。

    但是,开发人员通常更喜欢非托管代码,因为它执行速度更快,允许更灵活地使用指针,并且可以直接控制硬件。

    【讨论】:

    • 似乎 Aniruddha Varma 的问题与托管/非托管代码无关。他想知道为什么在 Java / .Net 程序中使用中间语言。
    【解决方案3】:

    字节码和 JVM 的“恶作剧”意味着代码总是以相同的方式解释,与运行它的平台无关。我记得很久以前模糊地读到英特尔和 AMD(以及其他处理器)以不同的方式执行一些逻辑操作,这导致这些处理器上的结果不同,并且可能导致一些跨平台错误。所以字节码解决了这个问题,结果总是不变的。

    另一方面,如果您知道自己仅针对一个平台进行编程并希望获得额外的性能,那么嵌入式软件开发(或低级语言)就可以发挥作用。如果您知道 Java 和 .NET性能并不那么重要。

    【讨论】:

      【解决方案4】:

      这是因为编译为本机代码会使您的程序平台指定。 但是,通过编译为中间语言,您的程序是可移植的,如果有指定平台的 JVM / CLR,您的程序可以在每个平台上运行。

      Java 和 .Net 都使用即时编译,因此它们可以提供可移植性,但与使用解释器相比仍然具有更好的性能。

      此外,微软已经将 Ngen 与 Visual Studio 一起提供,用于将 .Net 代码编译为本机代码:
      https://msdn.microsoft.com/en-us/library/6t9t5wcf(v=vs.110).aspx
      Ngen 和 .Net Native 的主要区别在于 Ngen 仍然依赖于 .Net Framework,而 .Net Native 将 .Net 所需的代码与程序一起编译,因此无需安装 .Net Framework。

      【讨论】:

        【解决方案5】:

        在java中生成字节码时,它特定于特定类型的架构,有助于java实现其“一次编译在任何地方运行”的能力。 除此之外,它占用的内存也非常少。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-08-04
          • 2013-12-29
          • 1970-01-01
          • 1970-01-01
          • 2011-12-19
          • 1970-01-01
          • 2011-10-28
          • 1970-01-01
          相关资源
          最近更新 更多