为什么我们需要/使用托管代码(而不是本地代码)?

8
我这里缺少一些基础知识。将源代码编译成字节码(Java)或中间语言(.NET),然后在JVM或CLR内运行它们有什么用处?

使用托管代码会降低性能(无论是轻微还是显著的),但是有什么好处呢?我知道有垃圾回收和内存管理,但即使如此,不需要这个中间层直接将源代码编译成本机代码是否更好呢?

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


1
字节码的一个巨大优势是能够在任何你实现了虚拟机的地方运行它。然而,在Windows中,这个范围受到限制,因为你只需要针对少数架构(如atom、x86等)进行目标定位。 - Sammy
.NET Native并不仅仅是“编译成机器码”,它本质上是提前进行jit,这样就不需要后续再进行jit。这仍然会转换为与jit期间完全相同的机器码;您对此过于简化,让它听起来像是神奇地变成了本地C ++。 - Krythic
@Krythic 我明白了。但那些不是我的措辞,我是在引用我提到的链接(.NET Native)中的内容。 - Arctic Vowel
Krythic 是不正确的。.NET Native 编译器使用与 Microsoft C++ 编译器相同的技术集合。事实上,用于 .NET Native 的代码生成技术集合几乎完全与我们为非本地提供的 JIT 不同。 - MattWhilden
5个回答

2

以下内容来自MSDN:

托管代码的优点

托管语言提供了一种通用的方式来处理内存管理和垃圾回收的细节,代价是一小部分的额外开销。这种权衡使你从容易出错的任务中解放出来,并让你编写更加紧凑、可读性更强、没有错误的程序。

非托管代码的优点

如果您使用非托管语言,例如C++,则必须编写额外的代码来管理内存和安全性,并在对象完成其目的后清理它们。这些琐事细节很复杂,与程序的预期功能无关,因此开发人员经常忽略这些任务、忽视它们或失去追踪。结果,非托管代码通常更昂贵、耗时更长,需要更多的程序员培训和纪律。

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


2
Aniruddha Varma的问题似乎不是关于托管/非托管代码的问题。他想知道为什么Java/.Net程序中使用中间语言。 - Mango Wong

2
除了其他答案中提到的所有内容,这种方法的主要好处在于开发和维护所实现的重要成本降低以及开发环境的大幅度提高可扩展性。
考虑没有中间语言的情况;你需要为每个支持的语言和平台开发和维护编译器。假设你有语言L1、L2和L3以及平台P1、P2和P3。这意味着你需要开发和维护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),那么您就可以让L1、L2和L3都在P4中运行。
这基本上是一种双赢的局面。

0

字节码和JVM的“恶作剧”意味着代码始终以相同的方式解释,与其运行的平台无关。我模糊地记得很久以前读过,英特尔和AMD(以及其他处理器)在某些逻辑操作上有所不同,这会导致这些处理器上的不同结果,从而可能导致一些跨平台错误。因此,字节码解决了这个问题,结果始终是恒定的。

另一方面,如果您知道自己只为一个平台编程并且需要额外的性能,则嵌入式软件开发(或低级语言)就派上用场了。当您知道性能并不重要时,Java和.NET最好使用。


0

这是因为编译成本地代码会使您的程序特定于平台。 然而,通过编译为中间语言,您的程序是可移植的,并且可以在每个平台上运行,如果有指定的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。


-1
在Java中,生成字节码是针对特定类型的架构进行的,这有助于Java实现其“编译一次,在任何地方运行”的能力。除此之外,它所需的内存非常少。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接