嵌入式Java会在下一代移动电话、智能卡、无线设备、游戏装置及其他许多嵌入式应用中扮演重要角色,关键在于选择哪一种实现方法。
Java 自从推出以来一直备受关注,不过在嵌入式系统设计师看来,其性能并不能令人满意。运行Java虚拟机(JVM)解释Java字节码这种方式对大多数嵌入式 应用来说占用空间过多,运行速度过慢。不过Sun的Java 2 Micro Edition(J2ME)改变了这种状况。
对嵌入式系统 设计师来说,Java有许多优点。作为一门编程语言,Java允许面向对象编程,又没有C++中存在的严重问题。例如,Java允许类继承,但不允许来自 多个父类,这就排除了产生混淆的可能;同样,Java防止了C++定义运算符时允许出现的不确定性。Java运行时环境还提供了有用属性,它通过先检查 JVM中的代码然后再执行来确保应用程序不会相互干扰,以及整个系统不会崩溃,如果代码试图改变系统的核心行为,它就无法运行。Java提供的内存管理功 能使得编程人员不必分配及释放内存,避免了内存泄露的可能,它还能通过垃圾收集方法,自动释放闲置内存。运行时环境甚至可以通过整合核心类库来简化程序分 配。
此外,Java在业界得到了广泛支持,这意味着有众多资源可以利用,包括小应用程序和经验丰富的编程人员,从而每次编写新应用程序无 需重复性工作。
但在上述这些优点之外,Java用于嵌入式开发的问题在于,大多数嵌入式应用面临Java没有处理好的两大约束:没有足够 的空间和时间。
Java开发的时间和空间约束
之所以会有时间上的约束,是嵌入式系统通常必须在短时间内对外部事件做出响 应,如果系统在下一个事件出现前没有处理好前一个事件,就无法完成任务。
时间上的约束还意味着需要确定性。设计师依靠软件元素,在已知或 者有限的时间内完成各自的任务,本身没有时间限制的任务(如等待循环)在执行时间攸关的任务时,能够暂停挂起。
嵌入式开发的空间约束来自 对成本和便携性的需求。设计师需要尽量少用内存,往往使得设计受微控制器的片上内存资源的制约。但这也有助于降低功耗,这是电池供电的便携系统所考虑的一 个重要因素。
在这些时间和空间的约束下Java很难正常工作。Java软件环境要与操作系统协同工作,并使用Java虚拟机把Java字 节码转换成系统处理器的本机语言。它还需要相当大的类库,作为核心系统的一部分。这两种因素大大增加了对系统内存的需求。
Java的解释 码运行起来本身就不如编译码快,这样一来,系统更难满足实时约束条件了。速度更快的处理器或许能帮上忙,但功耗因素往往使得嵌入式系统无法使用更快的处理 器。就算系统足够快,Java的垃圾收集算法也没有时间限制、不可中断,就不可能获得确定性。
J2ME定义两类Java
对 于Java在嵌入式开发中遇到的问题,J2ME可以解决其中的一部分。办法是缩减类库大小,并且改变垃圾收集算法。J2ME定义了两类Java:连接设备 配置(CDC)和连接有限设备配置(CLDC),让Java得以适用于诸多嵌入式系统,如下表所示。这些Java取代了较旧的嵌入式Java,而旧版本实 际上是用于定制应用的非标准版本的Java。
CDC 是一种功能齐全的Java,面向配有网络连接、32位处理器和供Java平台使用的2MB内存的设备。这个版本的Java允许设备以类似桌面机的方式,下 载及运行通用的小应用程序。PDA、家用电器和汽车导航系统就是适合的目标应用。
CLDC是一种精简版的 Java,面向运行时环境更加定制的应用。CLDC并不允许运行通用小应用程序,而是要求Java程序符合设备的约束条件。这样一来,Java“编写一 次、到处运行”的优势也就无从谈起,不过它仍保留了Java编程的其他优点。CLDC及其K虚拟机需要160KB的内存和16MHz的16位处理器。
Sun利用这两种配置,开发出了符合许多嵌入式系统设计空间约束的标准Java配置,Java社区制订的实时Java规范使得 实时和确定性问题迎刃而解。实时Java规范(RTSJ)V1.0提供了Java平台的标准扩展部分,并且改动了垃圾收集算法,确保了Java提供许多嵌 入式应用所需的确定性。
这就只剩下原始性能问题还没有加以解决。解决办法来自行业提高Java执行速度的一系列 方法,包括使用优化的JVM、执行前先把Java代码编译成本机码,使用及时(JIT)编程器以及使用硬件加速,每种方法各有优缺点。
与普通JVM相比,优化的JVM通常可以把执行速度提高2~2.5倍。不过,这种优化要针对特定处理器。提供优化的JVM的厂商 可能还会提供优化的类库和实时操作系统,能够与JVM密切合作,进一步提高软件性能。
不管有没有经过优化,使用 JVM仍需要解释工作,这就限制了程序的执行速度。把Java代码编译成本机码、然后再执行可以避免这种限制。这种情况下,Java成了类似C++的另一 种高级语言,限制执行速度的因素完全取决于编译器的代码效率。问题在于,与其他高级语言一样,必须在把代码植入程序内存之前,先进行这种编译,结果导致系 统缺乏灵活性,无法下载升级的Java代码或者是新的应用程序。
及时编译器力求通过“高速”编译Java代码以 便可以立即执行,重新获得这种灵活性。这带来了高性能和灵活性,但也增加了特定应用程序的启动时间,因为需要先开始编译。由于至少占用100KB的内存 (加上JVM和应用程序所需内存),使用及时编译器还加大了对系统内存的需求。
硬件加速Java
为了加快Java执行,又避开编译或者软件JVM的缺点,嵌入式开发人员可以求助于硬件加速器。这种设备把 JVM的部分或者全部任务转交给专用硬件去处理,因而性能比解释的Java提高了5~10倍。不过,硬件加速器并不接管所有任务,主机CPU仍处理特别复 杂或者很少使用的字节码。
半导体厂商采用了几种方法,通过硬件来加快Java的执行速度,致力于不同任务。
一种是使用硬件解释器。该解释器把进来的Java代码的大部分转化成本机码,从而给JVM省去了麻烦。例如Nazomi的 Jstar、InSilicon的JVX和ARM的Jazelle。大多数情况下,解释器拥有硅知识产权,这实际上扩大了处理器的指令集。
另一种方法就是使用协处理器。协处理器不仅解释字节码,还执行由此生成的机器码,让CPU完全得到解放。协处理器实际上是一种 处理器,使用Java字节码作为本机机器语言。有些协处理器如InSilicon公司的JVXtreme是纯粹的协处理器,而有些协处理器如Aurora VLSI公司的Espresso和DeCaf可以充当协处理器或者独立处理器,这样在另一个CPU处理用户界面等事务时,可以处理Java代码。 Ajile公司的aJ-100、DCT公司的Lightfoot和Zucotto公司的Xpresso都是协处理器。与解释器一样,这些协处理器往往作为 用于ASIC或者FPGA实现的核心。
第三种方式是利用硬件及时编译器高速编译Java字节码。这种设备有别于 硬件解释器,它不仅仅把软件从一种形式转换成另一种形式,实际上还能够编译,包括进行优化、重新安排代码执行次序等。Parthus公司的 MachStream就属于这一类。
有了这一系列加快Java代码执行速度的软硬件方案,嵌入式系统的Java 性能问题似乎可以得到解决了。遗憾的是,很难预测它们会给性能带来多大幅度的提升。加速器与其他系统单元的相互关系更是加大了预测难度。CPU架构、可用 系统内存的数量、实时操作系统(RTOS)、JVM、类库和硬件加速都可能影响系统的最终性能,甚至应用软件也会对性能产生影响。例如适用于 Internet设备的系统软硬件配置在机顶盒里面运行起来可能会比较慢,在移动电话上就完全不适合。
遗憾的 是,嵌入式设计师没有多少工具可以帮助自己测试非传统配置的性能。最有用的工具就是系统性能测试公司开发的SPEC JVM98基准测试。但SPEC JVM98不是为了满足嵌入式系统的测试需求,而是为联网和独立的客户机开发的,并且前提是假设完全实现了Java,并拥有完整的桌面系统环境,而很少有 嵌入式系统拥有这么丰富的资源。
Pendragon软件公司的CaffeineMark这个基准测试在嵌入式领 域颇为流行。与Dhrystone MIPS基准测试一样,CaffeineMark也是一种人工基准测试,仅仅测试几项Java特性,不包括浮点运算、垃圾收集和多线程这些项目,而对这些 嵌入式开发人员来说可能很重要。另外,没有标准配置可供基准测试来运行。因而,不同厂商的基准测试结果很难解读。
对 嵌入式Java而言,缺少测试工具问题也许不会长期存在。EDN嵌入式微处理器基准测试协会(EEMBC)已开始开发Java基准测试套件。EEMBC基 准测试准备采用诸多系统测试指标,包括垃圾收集时间和确定性、I/O性能、中断时延、内存使用以及测试过程中的系统功耗。还会包括详细的软件执行基准测 试,测试项目包括类加载时间、类方法执行、所用线程数量、每个线程所用时间、以及调用线程的时间。该协会计划在众多应用环境下进行基准测试,包括智能卡、 移动电话、掌上设备、Internet设备和机顶盒。
一旦这些工具准备到位,就可以根据预期应用来进行比较,从 而大大方便了开发人员选择嵌入式Java的诸多方案、确保系统的最终性能能够达到预期。那样,Java可以在将来的嵌入式系统开发当中扮演主角。