Java是在C++基础上改进了的面向对象的语言。它可以得到类的封装、继承、多态等的优异重用性的好处,Java的小应用程序(Java Applet)还特别适合于上网。看来,用Java开发上的网的嵌入式应用应是很理想的,可惜,实现起来受嵌入式设备硬件在速度、存储器容量、和其它资源的限制,加上桌面Java语言操作不到硬件,和执行时间的不确定性,使Java应用于嵌入式系统遇到新的问题。Sun公司按PersonalJava规范开发的J2ME(Java 2 Micro Edition),是专用研制用于开发嵌入式的上网个人消费类设备的。因此J2ME除有面向对象的优点外,还包含了Web能力。J2ME使用的是Java API的一个子集,它仅保留了API的关键特性并适当地作了简化。同时,又规定了两种可有存储模式:一个模式的内存为128~256KB,另一种模式是256KB以上的。其他,如类包也根据存储模式选用。
下面为避免混淆,在文中凡未加特殊说明的Java,统指桌面Java而言。
一、 问题提出
*常用的解释性Java(Java Applet)的执行速度慢,不适于嵌入式的应用。
*Java要求过大的内存。
*嵌入式设备要求操作硬件。因Java废弃了C语言所使用的指针,且在Web环境下使用了Java虚拟机(JVM),使Java无力直接甚至间接地用指针操作硬件。
*Java使用一些自动功能会引起执行时间的不确定性,成为嵌入式的大忌。如垃圾自动收集器。本是对于C的重大改进,但却因程序自动地回收垃圾,从而引入了实时的时间不确定性。
二、解决方案
使用AOT编译器
为解决解释性Java(Java Applet)执行速度过慢的问题,发展了AOT(ahead-of-time)编译器。大家喜欢在Internet上使用Java的一个原因是其字节码具有跨平台性,即同一Java代码可以运行于PC、Mac、Solaris,甚至于主机之上。为此,在英文叫它WORA(写一次即可通行于任意机)。这是因为每一操作系统平台上都有符合自己机型的专用Java虚拟机(JVM),由它对字节码进行解释运行。因为解释程序需先被解释再被执行,多了解释环节,延误数秒钟时间。如果是拨打电话,这个时间足以令人生厌。现在使用AOT(ahead-of-time)超前编译器,提前将解释码转换为本平台所用的并经优化过的二进制码,速度提高很多。现有Cygnus公司声称,它开发的AOT编译器执行速度是原解释程序的8倍。NewMonics说它的QuickPERC编译器是原解释程序的20倍。当然,AOT编译器也有不足,就是他牺牲了Java的WORA。
减少内存的占用
所有的面向对象语言,比C及汇编语言点用内存都多。这个问题对于桌面系统早已不再是考虑的因素了,如服务器平均占用数GB的内存已司空见惯。但是,对于嵌入式系统却不能不考虑。用Java开发的信息家电产品可能需要把内存限制到512KB以下。如果嵌入式系统使用的是规模为1MB的核心类库,那就是说,一句代码尚未写,内存早就不够用了。
为此,需要把用不到的类、类方法和代统统从程序中剔除。(AOT超前编译器可以帮助解决这个问题。)再就是自己开发本平台专用的,既短小高效、又符合Java API标准的Java核心类库。
开发能混合编程的IDE
一般认为,用C语言写的程序,指锗使用不当引起的缺陷占总缺陷的80%左右。Java语言,出于安全的考虑,才废弃了使用指针。但是,指针却能够最直接地访问到存储器和真实的硬件。现在,为在嵌入式Java中能够访问到硬件,不得不改用本地接口,即从嵌入式Java中利用能够访问到硬件的C语言函数来实行交*编程。这就意味着增加了复杂性。开发人员需要具备多语言以及多层次的混合编程和混合调试的能力。发展多语言多层次混合编程的IDE,无疑十分有助于一般开发人员完成这一相当复杂的课题。Metrowerks的CodeWorrior和IBM的VisualAge就是新开发的基于J2ME的这样的IDE。
克服时间的不确定性
Java最主要的问题是时间不确定性,主要来源于存储器残渣的自动收集再生器。这种垃圾收集再生器工作的时候,自动地决定何时停下其他程序的执行,再根据当时残渣的实际情况或长或短地完成任务。所以,它严重地干扰实时应用所要求的时间确定性。为解决这一问题,不同公司采用不同的方法和垃圾收集的算法。NewMonics的Real Time Executives和Windriver的FastJ都是保证绝对的确定时间,Sun公司用不同的办法但也保证具有实时的确定性。采用不同的编程技巧,譬如使用类型确定的线程局部存储,也可以避免因垃圾收集引发的冲突。
需保持跨平台的必要
AOT编译器生成的Java代码丧失了Java在其他操作平台上的执行能力。要想把Java的源代码再向其他平台移植,需要附加很大的劳动。面向对象的一个基本设计原理就是只要保持接品不变,那么,与接口交谈的代码在移植时就不受影响。所谓高级逻辑接口的隔离手法,事实上,就是将平台敏感的内容同移值无关的代码分离开来,并且分别提供同样功能的平台敏感程序。现在,针对嵌入式Java,目前还没有人做这项工作。
三、实际应用
Java是良好的嵌入式编程语言吗?
还不能这么说,至少现在是这样。因为在嵌入式系统中,Java如何应用要看具体情况而定。对于需要管理中断来完成重要任务的应用系统,就不宜于选用Java进行开 发,譬如引导登外星的飞行器系统就是这样。对于要求轻型、高效、任务重要、时间确定性要求极高的系统,也是只能局限于使用C语言和汇编。比如,点燃登陆外星的制动火箭系统,定时通过串行口获取关键信息一边做出决定的系统,定时报告航天器方位的系统等都不能使用Java。但是,需要不断与他人通信联系,以便对货运进行有效管理的手持系统,又最适合使用Java编程。因为,它既发扬了Java Applet固有的跨平台应用地Web环境的特点,又能充分利用服务器端的现成软件。
使用Java有时也并不完全取决于技术
立足于经济上的考虑,比单独的技术考虑更为重要。譬如,对于服务器,为了支持使用Java,宁愿多花费数千元扩大存储器是正确的。因为,从投入/产出的分析也得出同样的结论。又如手机,若为支持使用Java,哪性仅只需要多花一元钱去扩大存储器也是不可行的。因为,手机的生产是以行百万件的产量来考虑的,多花一元线,就意味着多花千百万元,诺大的数字远比技术的先进更为重要,是显而易见的。
实施嵌入式Java时需注意
Java用于嵌入式还是瓣生事物,需要探路前进,摸着石头过河,忌冒进和全面开花。应试探性地从使用现成的嵌入式J2ME开始,在它的通用性的开发环境下运行本平台的字节码。尽可能地顺着J2MME向前走,尽可能地顺着J2ME向前走,尽可能地走得远一点,只有在遇到特殊问题时才导求新的解决办法。新方法的采用并不一定能够解决问题,比如,AOT或半自动的垃圾收集器等可能并没有解决你的问题,也勿惊慌,要总结经验做出评价,继续前进,使嵌入式Java日罄完善。
要重视IDE的选用,好的IDE绝对是良好的助手。否则,你是单枪匹马,披荆斩棘,艰苦良多。