我有很强的C ++背景,从未对Java或C#有过深入的了解。但是,我对虚拟机的内部工作很好奇。我已经尝试了一些Windows exes,并发现实际的虚拟机是jvm和clr动态库。
现在困扰我的是:这些库如何与exe文件中的指令进行交互?
我唯一的猜测是字节码实际存储在exe文件的.data段中。它实际上将控制传递给.dll,它转换字节码指令。这是对的吗?
我无法找到有关该主题的任何内容,因此我们将不胜感激。
答案 0 :(得分:3)
好吧,在最基本的层面上,你做对了:有一个本机应用程序(运行时,如java.exe
)读取字节码并通过解释其中包含的指令“运行”它。 p>
您必须对该图片进行的第一个调整是,出于性能原因,大多数VM现在使用JIT编译,这意味着字节码不会被解释,而是在运行时编译为本机代码。
我唯一的猜测是字节码实际存储在exe文件的.data段中。
取决于。对于Java,您通常只有一个带有字节码的JAR文件,与启动的本机二进制文件分开。但是,是的,您可以将它们组合成一个可执行文件,然后包含本机启动程序代码(但可能不是所有依赖的共享库),字节码“作为数据”。
例如Eclipse在JVM上运行吗?你仍然通过exe发布它。
是。 Eclipse有一个“启动包装器exe”。但如果你看一下,它就非常小。它所做的只是设置一个启动画面并启动JVM(安装在您的系统上,而不是exe的一部分),并在其上抛出一些JAR文件(作为Eclipse的一部分安装,但不在exe内部)。
答案 1 :(得分:3)
您对IL存储位置的猜测在此处解决:
http://en.wikipedia.org/wiki/Portable_Executable#.NET.2C_metadata.2C_and_the_PE_format
您猜想C#基本上是正确的。可执行文件启动CLR并传递元数据和IL; CLR然后计算出“Main”的位置,为此获取IL,将其编译为x86(或其他)代码,并运行它。每个方法在第一次运行之前就“及时”编译,因此称为“jit编译器”。
这当然是一个大大简化的概述。如果您想了解有关.NET如何工作的更多信息,请从以下开始: