ComputerApplicationsandSoftwareVol125No.1
Jan.2008
J2ME应用程序性能优化的探讨
楚军华 李治柱
(上海交通大学电子信息和电气工程学院 上海200030)
摘 要 涉及如何通过现有的技术手段来提高J2ME应用程序的性能。分析和论述了性能优化的原则以及性能瓶颈的定位方法
等诸多方面,并提出了两种比较具体且有效的代码优化方式。关键词 J2ME 移动应用系统 性能优化
DISCUSSIONOFJ2MEAPPLICATIONPERFORMANCEOPTIMIZATION
ChuJunhua LiZhizhu
(SchoolofElectronicInformationandElectricalEngineering,ShanghaiJiaotongUniversity,Shanghai200030,China)
Abstract DiscussionismadeontheperformanceenhancementoftheJ2MEapplicationthroughtheexistingtechnicalmethod.Theprinci2pleofperformanceoptimizationisanalyzed,andthelocalizationmethodforperformancebottleneckisdiscussed.Twospecificandeffectivewaysforcodeoptimizationarepresented.
Keywords J2ME Mobileapplicationsystem Performanceoptimization
0 引 言
基于J2ME的移动应用系统遇到的主要问题是可以存储和运行J2ME程序的设备所具备的内存等资源很有限,导致系统功能受到很大限制。对于资源受限设备来说,哪怕很小的一点优化都会对程序的流畅运行起明显的作用。本文试图探讨以现有的技术来提高J2ME应用的性能,提出两种比较基本且有效的优化方式。
2.1 内存测试方法
为了测试内存使用情况,可以使用在java.lang.Runtime中所提供的两种方法:freeMemory()和totalMemory()函数。第一种方法告诉程序当前有多少字节的剩余内存可以使用。第二种方法给出在当前运行环境中总共的存储器大小。如为了查明一个对象到底需要使用多少内存,可以通过freeMemory()方法记下在定义该对象前的剩余内存;当对象定义结束后,再通过freeMemory()方法记下此时的剩余内存,然后将两次数字相减就得到了该对象所需要的内存。
1 确定性能优化的原则
快速而有效的代码是和优秀的设计、良好的算法、易于理解的数据结构以及它们的实现紧密联系的。单纯的优化处理不可能达到这一目的。但在现实中必须面对资源和响应速度的制约,不可避免地面对优化问题。在优化中一些可以借鉴的原则是:
a.不要为了优化而优化。只有确定优化是必须时才应给予考虑。
b.不要过早地进行优化。先做完它,再逐步完善。
c.优化的实施需小心进行。否则,优化可能带来bug。一个速度较慢但稳定的程序总比快速但不可靠的程序要好得多。
d.优化实施完毕后,应加以验证是否达到了想得到的效果,特别应在完整的系统中验证是否达到了优化的效果。
2.2 时间测试方法
采用传统的方法可以测试应用程序的运行速度。在开始运行程序时,记下开始时间;当程序运行结束时,记下结束时间,然后将两次时间相减就得到了程序的运行时间。获得程序当前的执行时间可以使用java.lang.System类中的CurrentTimeMillis()函数。
3 性能优化的策略方法
3.1 优化代码、减少内存占用
(1)通过减少应用程序功能,来减去一些不必要的类 仔
2 定位性能瓶颈的方法
在J2ME中只能使用一些传统的方法来测试代码以便于找
出最耗时的关键程序段。
细规划程序整体功能,尽可能将一些功能转移到服务器端来完成,以充分利用服务器充足的设备资源。去掉程序中每个不必要的类、函数和变量,尽量使用全局变量,一些不是全局的变量应该尽量重用。
(2)慎用应用程序中定义的内部类 每个类文件都有一定
收稿日期:2006-03-27。楚军华,硕士生,主研领域:移动信息管理系统应用。
© 1994-2008 China Academic Journal Electronic Publishing House. All rights reserved. http://www.cnki.net
第1期
楚军华等:J2ME应用程序性能优化的探讨 125
量的与之相关的系统开销。即便最普通的类也有系统开销。除
此以外,内部类也会在其他方面膨胀代码,因为编译器必须生成特殊的变量和方法,以便内部类可以访问包含它们的类的私有内容,所以不是别无选择的情况下就不要使用内部类。
(3)尽量使用现有的类 例如,基于CLDC的profile没有构造集合类,所以我们可以用内建的Hashtable和Vector类来实现之。构造MIDP程序时也可采用此法。
(4)破坏程序中的继承关系 允许把相关的代码放到一个或多个抽象类中,这是OOD中为提高程序间代码重用的推荐做法。虽然破坏继承关系与你所学知识相违背,但简化的继承关系更有意义,可以使程序结构更加简洁。特别的,当一个抽象类(可能来自其他项目)仅仅被继承一次时,这样的两个类很容易组合成一个,就可以减少相应的内存占用。
(5)循环的最佳化 有2个原则可以用来处理循环优化这方面的问题:一个就是一切可以在循环体外部预先计算好的值都不应该放到循环体内部计算;另一个就是避免在循环体中创建对象。如果在一个循环内部创建一个新对象,将导致程序性能可能受到双倍的影响,即当对象最初创建时,程序需要运行内存分配,而当该对象被垃圾收集器处理时,程序又要等待垃圾处理过程的运行。这意味着,每一次循环体的执行将激发系统运行一次垃圾收集器,这就导致循环体的执行速度与垃圾收集器的运行速度差不多。
(6)数组的初始化 这样的数组初始化代码:Intarr[]={0,l,2,3};当编译完以后,实际的效果就和以下代码一样:arr[0]=0;arr[1]=l;arr[2]=2;arr[3]=3。
代码在无意识中的增加量是不容忽视的。两种可选的优化办法是:一是把数据编码到一个String里面,运行时解码到数组。二是将数据作为二进制文件保存到程序包里面,并在运行时用classloader的getReourceAsStream方法访问。
(7)字符串的最佳化 通常我们都用String来处理字符串。其实我们也可以用stringBuffer来做相同的工作,而且,用StringBuffer能比用String减少大约一半的内存占用。这是因为String比StringBuffer多考虑了一些安全方面的问题而导致的。
(8)缩短名字长度如包名、类名、方法名和数据成员名 一个类文件包含太多的符号信息。缩短各量的名字可以缩小生成的类文件尺寸。这种节省不会特别明显,但多个类中进行总和的结果还是可观的。特别是在多个类中使用时,效果就更明显了。
第一步先找出对应的C函数的名字。这一步需要使用一个叫做JCC(JavaCodeCompact)的工具。通过JCC可以将Java类文件结合在一起,成为一个唯一的C原始文件。之后这个文件可以被编译,并直接与虚拟机连接起来,省下了运行时的load时间,并大幅降低虚拟机的激活时间。并且它只会加载那些会被用到的classmember,而不会加载不会被用到的classmember。执行JCC工具程序来产生新的nativeFunctionTable.c和ROMja2vaUnix.c文件。在文件中找出有getStyle字符串的一行。比如在ROMjavaUnix.c中有这一行:
externvoidJava_javax_microedition_lcdui_Font_getstyle(void)。
则与Java程序中Font类的getStyle()方法对应的native
method的名称必须是这个函数名。
第二步编写对应的nativemethod。在nativemethod的源文件中需要包括两个部分:
include文件 这里首先要include一个很重要的头文件
global.h,这个头文件将会包含KVM中所有与编写nativemethod
有关的头文件。然后再include需要的额外文件。
nativecode 参数的存取是nativecode中非常重要的部分。从虚拟机内部调用一个native函数时,这个函数的参数将会依次位于Java栈的顶端。但如果这是个静态方法的话,Java栈中不会存放实例的指针。KVM中用来从Javastack中存取参数的宏如表l所示。
表1 KVM中用来存取参数的宏
C参数类型char,byte,int,longfloatlong64,ulong64
doublepointerType
Pop参数用的宏PopStack()PopStackAsType(float)
PopLong()PopDouble()PopStackAsType(pointerType)
PushPushStack()PushStackAsType(float)
PushLong()PushDouble()PushStackAsType(pointerType)
第三步更改Makefile,将新的C文件编译成目标文件。第四步执行make,生成native化后的KVM可执行文件。(2)部分JavaAPI的改写举例JavaAPI将一些比较基本的、或者比较复杂的类及其方法提供给开发人员使用,从而大大提高了程序开发的效率。这些用Java写成的API的代码可能是非常复杂的,其中一些API的执行速度决定了整个KVM和应用程序的运行效率。因此,将这部分常用的瓶颈API改写成nativemethod,可以很大地提高KVM和应用程序的运行效率。
常用的关键API:经过对系统程序代码的分析、总结,归纳出以下的一些JavaAPI,在本系统中的使用频率比较高,而且对KVM和程序执行效率的影响比较大:
javax.microedition.lcdui.Canvas.paint(Graphicsg)javax.microedition.lcdui.Canvas.repaint()javax.microedition.io.Connector.open(String;int)javax.microedition.io.Connector.openInputStream(String)javax.microedition.mandListener)
javax.microedition.lcdui.Font.getFont(intfoniSPecifier)
javax.microedition.lcdui.Graphics.drawImage(Imageimg,intx,inty,intanchor)
lcdui.Displayable.
setCommandListener(Com2
3.2 用nativemethod提高KVM的执行速度
(1)Javamethodnative化的方法
该方法所需要做的工作主要分成Java端的处理和native
code的编写两部分:
Java端的处理:在Java端需要做的主要是修改Javamethod的声明,方法如下:直接将原method的内容清空,并且在method的声明前加上native标示符。比如原来的getStyle()方法如下所示:publicintgetStyle(){returnstyle;}
把它native化应改写成如下的形式:publicnativeintgetstyle()
不论什么性质的(public、private、protected或synchronized)的instancemethod或staticmethod都用以上方式来改写方法的声明,并清空方法的内容。
nativecode的编写:分四步来完成。
© 1994-2008 China Academic Journal Electronic Publishing House. All rights reserved. http://www.cnki.net
126
计算机应用与软件2008年
javax.microedition.lcdui.GraPhics.drawStrihg(Stringstr,intx,inty,intanchor)
javax.microedition.lcdui.Graphics.setColor(intRGB)javax.microedition.1cdul.Graphics.setFont(Fontfont)javax.microedition.lcdui.Image.createlmage(Imagesource)javax.microedition.lcdui.Image.getGraphics()javax.microedition.lcdui.Image.getHeight()javax.microedition.lcdui.Image.getWidth()
javax.microedition.rms.RecordStore.addRecord(byte[]data,intoff2set,intnumBytes)
javax.microedition.rms.RecordStore.getName()
javax.microedition.rms.RecordStore.getRecord(intrecordld)
javax.microedition.rms.RecordStore.getRecord(intrecordld,byte[]buffer,intoffset)
javax.microedition.rms.RecordStore.openRecordStore(StringRSName,booleanIfNecessary)
[2]JamesKeogh.J2ME开发大全.潘颖,王磊,译.北京:清华大学出版
社,2004.
[3]闻怡洋.J2MEMIDP1.0/2.0无线设备编程指南.北京:北京大学出
版社,2004.
[4]温尚书.J2ME无线通信实用案例教程.北京:清华大学出版社,
2003.
[5]林胜利,刘华军.精通J2ME无线编程.北京:中国铁道出版社,
2004.
(上接第72页)
BV
MaximumEntropy
WF
2
χ
96.4697.4794.4385.57
98.7098.4798.6894.68
97.7898.1396.8591.13
97.5797.9696.5189.89
TF2IDF
J2ME的本地永久存储库(javax.microedition.rms.Record2
Store)部分因为涉及较多的数据操作,也会占用较大的CPU资
源,在这部分的方法中,选择了以下方法进行native化:
javax.microedition.rms.RecordStore.addRecord(byte[]data,intof2feet,intnumBytes)
对表中的实验结果进行分析,可以得出如下结论:
(1)在各种模型中,词频特征函数一般均比其它特征函数性能有所提高,充分说明了词频特征函数在邮件过滤中的作用。
(2)除了TF2IDF特征函数外,基于最大熵模型的邮件过滤性能都好于其它常用的邮件过滤方法,最大熵模型在邮件过滤中表现出了良好的性能。
(3)native化前后程序的运行效率比较
针对以上改写的部分,设计了一个测试方案来比较native化前后程序运行效率的差异。创建一个本地记录存储库,将一个1K的数据作为一条记录存进存储库,重复存储100条。在此过程的开始和结束时显示系统当前时间,两个时间值的差就是此过程大概花费的时间。
在未native化的J2ME环境和native化后的J2ME环境中执行以上过程各5次(在Windows的模拟环境中进行,硬件及外部条件基本相同),取5次结果的平均值作为最后结果加以比较。由结果可以看出,native化前后KVM和程序的运行效率有了较大的提高。具体数据如表2。
表2 测试方案的结果
本地记录存储未native化(单位:毫秒)native化后(单位:毫秒)
12345
342340400398385373
515065646058
4 结束语
本文将信号处理领域中应用广泛的最大熵模型引入到邮件
过滤中,提出了基于最大熵模型的邮件过滤系统模型,改进了特征函数的定义,应用平滑技术处理“稀疏”事件,并与其它常用邮件过滤方法进行了对比实验。实验结果表明,最大熵模型在邮件过滤中表现出了良好的性能。在今后的工作中,将对邮件特征提取、特征函数定义、平滑技术等作进一步研究,以提高基于最大熵模型的邮件过滤系统的性能。
参考文献
[1]上海艾瑞市场咨询有限公司.第三次反垃圾邮件市场研究报告,
2004,9:6.
[2]潘文锋.基于内容的垃圾邮件过滤研究[D].中国科学院研究生
院,2004:429.
[3]AdwaitRatnaparkhi.ASimpleIntroductiontoMaximumEntropyModes
forNaturalLanguageProcessing[R].TechnicalReport97208,InstituteforResearchinCognitiveScience,UniversityofPennsylvania,1997.[4]李荣陆,王建会,陈晓云,等.使用最大熵模型进行中文文本分类
[J].计算机研究与发展,2005,42(1):942101.
[5]YangYiming,PedersonJO.AComparativeStudyonFeatureSelection
inTextCategorization[A].Proceedingsofthe14thInternationalCon2ferenceonMachinelearning.Nashville:MorganKaufmann,1997:4122420.
[6]MartinSC,NeyH,ZaploJ.Smoothingmethodsinmaximumentropy
languagemodeling[A].ICASSP99,1999,1:5452548.
[7]汉语词法分析ICTCLAS系统[EB/OL].http://mtgroup.ict.ac.
cn/,中国科学院计算技术研究所.
[8]OpenNLPMaximumEntropyPackage[CP/OL].http://maxent.source2
forge.net/.
[9]ChristopherDManning,HinrichSchutze.统计自然语言处理基础.苑
平均
4 结束语
J2ME应用的性能优化有两种比较基本且有效的方式:一种
优化方法是最基本通用的优化代码、减少内存占用,这是J2ME
编程所必须进行的优化,也是副作用最小的优化方法;另一种优化方法是将一些常用的API改写为nativemethod。这种方法较复杂,会降低程序的可移植性,增加代码体积,但可较大地提升程序的执行速度。
参考
国铁道出版社,2002.
文献
[1]卢军.J2ME应用程序开发———手机、PDA程序开发捷径.北京:中
春法,等译.电子工业出版社,2005:356.
© 1994-2008 China Academic Journal Electronic Publishing House. All rights reserved. http://www.cnki.net
因篇幅问题不能全部显示,请点此查看更多更全内容