从理论上讲,我可以获得openJDK JIT,并将我的java代码编译为native吗?

时间:2011-02-15 08:51:04

标签: java jit native-code

我只是想知道如何摆脱java jre依赖并生成本机代码并将编译后的代码作为应用程序提供?

那么可能吗?

P.S。我知道gcj编译器它的作用是什么?

4 个答案:

答案 0 :(得分:3)

编译后的字节代码仍然依赖于java虚拟机。 JIT无法在JVM容器外部创建“有意义”的代码。是的,结果是针对目标平台的一堆有效指令。但是你仍然需要实际的堆栈,堆和垃圾收集器(仅列举一些必需的构建块)。

答案 1 :(得分:1)

Excelsior有一个非常好的Java2Native编译器。我很乐意使用它,但遗憾的是我们的项目用这个编译器编译需要8个小时。由此产生的应用程序速度令人印象深刻。

答案 2 :(得分:1)

理论上,可以为语言使用任何解释器并将其转换为使用该语言生成本机代码的编译器。这与称为Futamura projections的一系列方程有关。高级想法本质上是“欺骗”你如何定义编译器。假设对于某些语言L,我有一个解释器I(p),给定用语言L编写的程序p,解释该程序。现在,我假设解释器I直接在机器代码中表示。进一步假设我有一个名为mix的程序,给定一个机器代码程序和该程序的一系列输入,产生一个新的机器代码程序,它是一个初始程序,其输入被固定为指定的输入。例如,如果我编译了这个C ++程序:

#include <iostream>
using namespace std;

int main() {
    string message;
    cin >> message;
    cout << message << endl;
}

然后使用mix将程序与输入“Hello”混合,我会得到一个总是打印出消息“Hello”的程序。换句话说,就好像我写了这个程序:

#include <iostream>
using namespace std;

int main() {
    cout << "Hello" << endl;
}

事实证明,建立这个程序是可能的。我可以这样做,例如,通过查看机器代码,查看您尝试从控制台读取输入的每个位置,然后将其替换为调用函数的代码,而不是从硬编码字符串中读取。

现在,考虑如果你要运行这个mix程序作为输入解释器I和一些程序p会发生什么。然后,结果将是一个机器代码程序,它等同于我在输入p上运行的程序。换句话说,你刚刚构建了一个机器代码程序,它模拟了如果你在程序上运行解释器会发生什么 - 这是一个执行程序p的机器代码程序!

当然,这种结构完全不切实际。据我所知,没有人写过mix,如果他们这样做了,你通过将解释器变成编译器而制作的任何程序都会效率低下,因为它根本不会被优化。

关于你是否可以使用JVM的JIT并使用它来为Java程序生成原始机器代码的原始问题,我不确定,因为我没有查看源代码,但我强烈怀疑它。机器代码几乎肯定包含可以回调到JVM以执行特定任务(例如,垃圾收集,类加载等)的挂钩,这会使生成的代码无法在独立环境中运行。然而,尝试这样做是一个非常酷的想法,我希望这个答案能够对它背后的理论有所启发!

答案 3 :(得分:0)

请注意,这个问题类似于“我可以摆脱Windows并让我的Windows程序在没有操作系统的裸机上运行”吗?

Java程序期望有大量的类可供使用,这是JRE提供的,并且任何编译器或模拟器也必须提供。

可以做的是查看一个启动器,它允许你将自己的JRE带到你的应用程序中 - 这只能在JRE的平台上运行,但你已经愿意了是特定于平台的。有几个存在 - 我鼓励你看一下Stack Overflow上关于如何做的许多问题。