从理论上讲,我可以获得 openJDK JIT 并将我的 java 代码编译为本机吗?
I just wonder how can I get rid of the java jre dependency and produce native code and deliver the compiled code as the application?
So does it possible?
P.S. I know about gcj compiler is it what its doing ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
编译后的字节码仍然依赖于java虚拟机。 JIT 无法创建在 JVM 容器之外“有意义”的代码。是的,结果是一堆针对目标平台的有效指令。但您仍然需要实际的堆栈、堆和垃圾收集器(仅举几个必需的构建块)。
The compiled byte code will still depend on the java virtual machine. A JIT can't create code that "makes any sense" outside the JVM container. Yes, the result is a bunch of valid instructions for the target platform. But you still need the actual stack, heap and garbage collector (just to name a few required building blocks).
Excelsior 有一个非常好的 Java2Native 编译器。我很想使用它,但遗憾的是我们的项目需要 8 个小时才能使用此编译器进行编译。该应用程序的最终速度令人印象深刻。
Excelsior has a very good Java2Native compiler. I would love to use it, but sadly our project takes 8 hours to compile with this compiler. The resulting speed of the app is impressive thought.
理论上,可以采用任何一种语言的解释器并将其转换为生成该语言的本机代码的编译器。这与一系列称为 Futamura 投影 的方程有关。高层的想法本质上是“欺骗”你定义编译器的方式。假设对于某种语言 LI 有一个解释器 I(p),给定一个用语言 L 编写的程序 p,它解释该程序。现在,我假设解释器 I 直接用机器代码表示。进一步假设我有一个名为 mix 的程序,给定一个机器代码程序和该程序的一系列输入,会生成一个新的机器代码程序,该程序是初始程序,其输入固定为指定的输入。例如,如果我编译了这个 C++ 程序:
然后使用
mix
将程序与输入“Hello”混合,我会得到一个始终打印出消息“Hello”的程序。换句话说,就好像我已经编写了这个程序:事实证明可以构建这个程序。例如,我可以通过查看机器代码,查看您尝试从控制台读取输入的每个位置,然后将其替换为调用函数以从硬编码字符串读取的代码。
现在,考虑一下如果您要运行这个 mix 程序,并将解释器 I 和某个程序 p 作为输入,会发生什么。那么结果将是一个机器代码程序,相当于我在输入 p 上运行的程序。换句话说,您刚刚构建了一个机器代码程序,它模拟了在该程序上运行解释器时会发生的情况 - 这是一个执行程序 p! 的机器代码程序!
当然,这种构造是完全不切实际的。据我所知,没有人编写过
mix
,如果他们这样做了,那么通过将解释器转变为编译器而编写的任何程序都将非常低效,因为它根本不会得到优化。至于你最初的问题,即是否可以采用 JVM 的 JIT 并使用它来为 Java 程序生成原始机器代码,我不确定,因为我还没有查看源代码,但我强烈怀疑它。机器代码几乎肯定包含会回调 JVM 来执行特定任务(例如,垃圾收集、类加载等)的钩子,这将使生成的代码无法在独立环境中运行。然而,尝试这样做是一个非常酷的想法,我希望这个答案能够阐明其背后的理论!
In theory, it's possible to take any interpreter for a language and turn it into a compiler that produces native code in that language. This is related to a series of equations called the Futamura projections. The high-level idea is essentially to "cheat" at how you define a compiler. Suppose that for some language L I have an interpreter I(p) that, given a program p written in language L, interprets that program. Now, I assume that interpreter I is represented directly in machine code. Further suppose that I have a program called
mix
that, given a machine code program and a sequence of input to that program, produces a new machine code program that is the initial program with its input fixed to be the specified input. For example, if I compiled this C++ program:And then used
mix
to mix the program with the input "Hello," I'd get a program that always prints out the message "Hello". In other words, it would be as if I had written this program:It turns out that it's possible to build this program. I could do this, for example, by looking at the machine code, looking at every place that you try to read input from the console, and then replacing that with code that calls a function to instead read from a hardcoded string.
Now, consider what would happen if you were to run this
mix
program taking as input an interpreter I and some program p. Then the result of this would be a machine code program that is equivalent to the program I running on input p. In other words, you've just constructed a machine-code program that simulates what would happen if you were to run the interpreter on the program - which is a machine-code program that executes the program p!Of course, this construction is completely impractical. To the best of my knowledge no one has written
mix
, and if they did, any program you made by turning an interpreter into a compiler would be woefully inefficient because it wouldn't be at all optimized.As to your original question about whether you could take the JVM's JIT and use it to produce raw machine code for a Java program, I'm not sure since I haven't looked at the source code, but I strongly doubt it. The machine code almost certainly contains hooks that would call back into the JVM for specific tasks (for example, garbage collection, class loading, etc.), which would make the generated code not work in a standalone environment. However, it is a really cool idea to try to do this, and I hope that this answer shines some light on the theory behind it!
请注意,这个问题类似于“我可以摆脱Windows,让我的Windows程序在没有操作系统的裸机上运行”吗?
Java 程序期望有大量可用的类,这是 JRE 提供的,并且任何编译器或模拟器也必须提供。
然而,您可以做的是查看一个启动器,它允许您将自己的 JRE 与您的应用程序一起使用 - 这仅适用于 JRE 平台,但您已经愿意成为平台具体的。存在几个 - 我鼓励您查看 Stack Overflow 上已有的有关如何做到这一点的许多问题。
Please note that this question is similar to "Can I get rid of Windows and let my Windows program run on the bare metal without an operating system"?
Java programs expect a large set of classes to be readily available, which is what the JRE provides, and that any compiler or emulator will have to provide too.
What you can do however is to look at a launcher which will allow you to bring your own JRE with your application - this will only work at the platform of the JRE, but you are already willing to be platform specific. Several exist - I encourage you to look at the many questions already on Stack Overflow about how to do that.