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