Java本机编译(转载),java本编译转载
Java本机编译(转载),java本编译转载
衡量 Java 本机编译从 Java 源程序生成本机代码的优缺点 原文: http://www.ibm.com/developerworks/cn/java/j-native/ |
级别: 初级 Martyn Honeyford, 软件工程师, IBM 英国实验室 2002 年 1 月 18 日 一开始引入 Java 本机编译时,它似乎一定能胜过 JVM,抛弃 Java 平台极力争取的平台无关性。但是即使本机编译越来越流行,并且市场上的本机编译器越来越多,它要真正取代 Java 的可移植性还有一段路要走。不幸的是,就连该技术成熟到足以解决目前让许多人头疼的 Java 性能问题也还尚需时日。请在 论坛中将您对本文的想法与作者和其它读者一起共享。 尽管 Java 语言有许多优点,但是仍然存在几个问题限制了在关键项目中的使用。它们包括执行速度、内存占用、磁盘占用以及 JVM 可用性。虽然 JIT 编译器极大改进了平台的执行速度,J2ME 大幅降低内存占用,但是在许多领域中,Java 应用程序完全无法和它们本机的竞争对手(通常是 C/C++)竞争。为了解决这些问题,许多开发人员已经转向使用 Java 本机编译器,它们允许用 Java 语言编写应用程序,然后将它们编译成本机可执行程序。这种解决方案将以平台无关性为代价,但是它可以导致更快的执行速度和更小的内存占用,这些对于当今许多应用程序都很关键。 为使您能快速掌握 Java 本机编译技术,我们将首先讨论代码编译基础,包括为什么许多开发人员正在使用 Java 本机编译器编译他们的应用程序的简要概述。接下来,我们将使用自由软件编译器和两个不同的应用程序(一个很简单,另一个复杂一些)来测试 Java 本机编译的结果。这些示例和所产生的度量结果将作为研究如何比较最新的 Java 本机编译器和 JVM 的第一手资料。 代码编译基础 要理解本文讨论的内容,您应该熟悉三种最常用的代码编译方法:
使用 Java 编译器编译 Java 代码是最简单的。我们只要用 Java 语言编写源代码,使用 Java 编译器将源代码编译成 Java 字节码,然后就可以在任何安装了 JVM 的硬件/OS 平台上执行结果了。其缺点是 Java 依赖于 JVM 来实现其特点“一次编写,随处运行”可移植性;不仅要在运行 Java 应用程序的任何平台上安装有可用的 JVM,而且必须还有大量系统资源(内存和磁盘空间)用以支持 JVM。因此,许多开发人员仍然依靠不太灵活但却更具针对性的语言,例如,C/C++。 编译 C/C++ 源程序与编译 Java 源程序相似。只要编写了代码,我们通过一个针对特定硬件/OS 平台的编译器和链接器来运行它。只有在目标平台上才可以执行生成的应用程序,但是不需要安装 JVM(虽然它可能需要一些支持共享库,这取决于所使用的语言)。几乎使用这种方法开发的最简单的应用程序都必须针对每个要运行它们的硬件/OS 平台单独定制。 第三种方法尝试结合以上两种解决方案的优点,允许开发人员使用 Java 语言编写应用程序,然后将它们编译成本机可执行程序。编写了 Java 代码之后,就可以通过 Java 编译器生成 Java 字节码,然后将 Java 字节码编译成本机代码来运行它,或者在 Java 本机编译器中直接运行 Java 代码。需要的步骤数取决于所使用的编译器的需求。 这种方法的优点是可以在 未安装 JVM的目标平台上执行结果代码。这样做的目的是使 Java 应用程序以更快的速度执行,大幅降低运行所需的磁盘空间和内存(虽然有必要为 Java 本机编译器提供支持资源库)。 编译器的目标平台、它们提供的 Java 支持级别以及它们使用的系统资源的数量都是不相同的。在本文的 参考资料一节中可以找到一些当前可用的本机编译器的清单。 关于测试设置 对市场上每种本机编译器的功能部件和性能进行比较已经大大超越了本文的范围。我使用一种编译器 ― GNU 编译器 Java 编程语言版(GNU Compiler for the Java Programming Language, GCJ)作为示例来详细说明本机编译的过程与结果。GCJ 是一种为 GNU 编译器集(GNU Compiler Collection,GCC)开发的编译器,GNU 编译器集是 GNU 项目的一部分。与其它出自 GNU 项目的所有软件一样,GCJ 是双重意义上的自由软件,因此可以很容易地获取(请参阅 参考资料)。如果您正在认真考虑您产品的本机编译途径,当然应该尽可能多地评估编译器,或许可以使用本文中建立的标准。 我的测试系统硬件是一台装有 450 MHz Pentium II 处理器和 320 MB 内存的 PC 机。操作系统是最近安装的 Mandrake 8.1 Linux 分发版。这个分发版带有 GCJ 的 3.0.1 版本,它包含在 GCC 3.0.1 中并且作为 8.1 Mandrake 分发版一部分提供。 我已经运行了两个独立的应用程序,一个很简单,另一个复杂一些。为了比较系统和 Java 平台的性能,我将应用程序编译成 Java 字节码。我使用 Sun JDK 版本 1.3.1.02 Linux 版来编译 Java 代码,然后在下列 JVM 上测试结果类:
为实现本文的目的,我测量了执行速度、执行内存开销和磁盘空间。 测试 1:Prime.java 第一个测试应用程序很简单,由单一类 prime.java 组成。这个应用程序实现一个非常基本的搜索质数的算法。 清单 1 显示了 prime.java 的源代码。 清单 1. prime.java 的源代码
如您所见,代码从 0 循环到 50000。运行时,它尝试用每个它遇到的数除以每个小于这个数的数字,以找出是否有余数。(不可否认,这是搜索质数的一种蛮力方法,但是它可以满足该示例的需要。) 我使用下列命令将 prime.java 编译成本机可执行程序:
参数 为了编译 Java 字节码测试,我使用了下列命令:
接下来,对于每个测试 JVM,我使用下列命令调用代码:
prime.java 的测试结果 如前所述,我测试了执行速度、内存使用和磁盘空间使用情况。下表详细说明了第一个测试的结果。 表 1. Prime.java:执行速度
表 2. Prime.java:内存使用
请注意,VM 大小等于进程映象的总和。这包括该进程所使用的所有代码、数据和共享库,包括已经交换出去的页面。VM 驻留集大小(RSS)等于实际驻留在 RAM 中的进程(代码和数据)部分的大小,包括共享库。这给出了一个进程大概使用多少 RAM 的近似值。 简单来说,如果一个进程分配了大量内存,这会显示在 VM 大小中,但是直到真正被使用(例如,读或写)时才会显示在 VM RSS 中。实际上,VM RSS 是更重要的测量指标,因为它更准确地反映了系统的性能。 表 3. Prime.java:磁盘空间使用
请注意,表 3 中显示的测量不包含共享库和 JVM,并且是剥去可执行程序后进行测量的。 测试 2:SciMark 2 对于第二个测试,我使用了一个更复杂的 Java 应用程序 SciMark 2 Java 基准测试程序。可以免费获得本文使用的命令行版本(请参阅 参考资料)。SciMark 2 是一个很复杂的应用程序。它实现了许多用来准确地评测 JVM 的效率的基准测试程序。 我使用下列命令将 SciMark 2 编译成本机可执行程序:
然后,我使用下列命令将应用程序编译成 Java 字节码:
SciMark 2 基准测试程序能以两种模式运行,正常模式和大模式。您使用的模式决定使用的问题集的大小。我已经用这两种模式运行了测试。 我使用下列命令以正常模式调用代码:
对于更大的问题集,我使用下列命令:
SciMark 2 的测试结果 以下各表显示了编译 SciMark 2 的结果。请注意结果中正常模式与大模式的区别。 表 4. SciMark 2,正常模式:执行速度
表 5. SciMark 2,正常模式:内存使用
表 6. SciMark 2,大模式:执行速度
表 7. SciMark 2,大模式:内存使用
表 8. SciMark 2:两种模式使用的磁盘空间
再次声明,表 8 中的测量不包括共享库和 JVM,并且剥去了可执行程序后测量的。 本机编译的优缺点 从上面的测试结果应该明显看出,Java 本机编译究竟是成功还是失败还难有定论。某些基准测试程序显示在本机编译的可执行程序比使用某些 JVM 版本快;另外一些则相反。同样,不同 JVM 之间,某些操作的速度也大相径庭。执行的“工作集”内存测试显示执行时在内存使用方面并没有很大差别。要进一步探索该领域,可以采用不同的垃圾信息收集方案来进行本机和 JVM 测试。 本机版本只是在磁盘空间使用方面明显优于 JVM 版本,而且只有当考虑到 JVM 的大小时,这才能成立。虽然类本身很小,但是所测试的 JVM 却很大(IBM 和 Sun JVM 的 jre 子目录中的递归目录清单显示仅是 JRE 就占用了 50 MB 磁盘空间)。但是,请不要忘记还可以使用许多更小的 JVM,虽然 JVM 和单个应用程序的组合比本机可执行程序与 GCJ 运行时库 libgcj.so(少于 3 MB)的组合大得多,但是本机版本的可执行程序的大小却大很多。因此,在需要大量应用程序的情况下,JVM 版本可能是最终的赢家。 除了这些有点模糊的结果之外,使用 Java 本机编译还可能产生许多潜在问题。它们是:
结束语 当开发应用程序时,通常确定 Java 本机编译是否适合您的特定环境的唯一实际方法是完成一个问题解决周期。 尽管 Java 本机编译技术还比较稚嫩,并且缺少明确的结果,但它却是 Java 语言中一个激动人心的新领域。利用现有选项的最佳方法是,或许可以使用本文中建立的某些方法和标准亲自研究和测试 Java 本机编译。 虽然本机编译不会取代 JVM(许多人认为它会取代 JVM),但是已经证明,对于某些应用程序和环境,它是正确的解决方案。本机编译将 Java 语言的使用范围扩展到一些新领域,短短几年前在这些领域中还无法应用 Java 语言。整体而言,这仅对于 Java 语言和 Java 社区是件好事。 参考资料
可选择的 Java 本机编译器
关于作者
|
相关文章
- 暂无相关文章
用户点评