J2ME手机开发之内存优化攻略

在C或C++开发过程中,内存溢出问题可谓是经常让开发人员极其痛苦的事情,稍不注意问题就产生,甚至引发隐含的漏洞产生。JAVA正是在C++的优秀品质中继承下来的产物,拥有垃圾回收机制是JAVA虚拟机在C++继承过程中进化的一个重要地方,垃圾回收机制能在对象没被使用之后的某个时间将对象进行回收,从而能使无用对象占据的内存得到释放。但是,这仅仅对有足够内存的Server服务器主机跟PC机上的虚拟机有用,对于内存极其珍贵的设备来说垃圾回收机制却显得有点无能为力,英雄无用武之地。虽然随着手机硬件的不断升级,智能手机中的手机内存以及CPU资源大大得到提升,但是目前用户手中的手机并无法普遍达到这种水平,因此在J2ME设计开发过程中我们需要很好的考虑到每一寸内存土地的利用。今天参考了有关资料,并对J2ME开发过程中的内存相关内容做个归纳,以增加对内存的使用有更好的理解。
      一、程序内存情况分析
      1、在使用WTK中,我们可以调用工具中的Memory Monitor来查看程序的内存使用情况。
      2、使用相对于的手机模拟器内存监视器来对程序使用内存进行监视。
      3、Runtime类提供了查看剩余内存的方法freeMemory()。

      二、程序内存占用分析
      一个软件在运行过程中占据内存主要是程序代码和程序所使用的各类资源,包括文字文件资源、图片、音乐等多媒体资源。
      而在JAVA虚拟机中,java代码最终是被编译成class文件的字节码形式并且随着程序的启动而加载到内存中,因此经过编译之后的字节码文件的容量大小,将会影响程序最终占用内存的大小,而字节码文件的大小则是由程序代码中类的个数、变量名称以及方法名的长度、字符串以及静态常量的长度和大小等因素决定的。
      在手机应用程序中特别在游戏开发中,都需要使用各类的资源,使得游戏内存丰富多彩,而这些资源将是程序占据更多资源的原因。同样的,在游戏场景中,设计到很多对话内容,因此涉及到很多文字存储文件(使用文件存储而不是在程序中声明字符串的作用是在需要时候才读取内容,防止过多字符串占据过大内存)。
      声音也是一种极其占据内存的资源,因此在程序当中也需要对声效等资源的控制。

      三、内存优化方法攻略
      1、代码优化
      尽量使用较短的变量名称和方法名称,减少类中成员变量跟成员方法的数量,多使用局部变量而少使用全局变量,减少程序总体的代码行数,在程序测试确定无错情况下可以去掉异常处理的try-catch语句,对常量跟字符串过多的程序中使用文件存储形式以使用时候再读取,对不使用的对象及时指向为null,对占据大内存的程序或资源的数据流读取使用后及时释放资源并使用System.gc()方法回收垃圾资源。
      2、图片优化
      在图片使用中,我们通常使用图形压缩工具或算法对图片大小进行压缩,但是这样的作用仅仅是较小了J2ME程序最终产生的JAR文件包大小,但无法减少图片在被使用时候对内存的消耗。据有关资料介绍,图片的内存在内存中的大小只跟图片被装载后的高度跟宽度有关,而跟图片本身体积大小无关,计算公式为内存占用量=宽*高*像素字节数。
      因此在图片优化中可以使用减小图片的高宽、使用图片分割编辑工具对图片进行分割,充分利用图片的空间;在使用的时候才载入相关的图片,而在无用的时候及时销毁图片对象;对每一张图片声明一个对象变量。
      3、声效资源优化
      对声音采用字节流ByteArrayInputStream来创建Player对象;在对声音对象的回收前停止声音的播放;其次在每次播放声音前先对声音对象进行判断,如对象存在则先停止后再进行播放。
      4、有关字符串处理
      对字符串的处理使用StringBuffer来操作,因为使用方法append时是同一个对象上的操作,而如果采用“+”操作字符串则会每次创建新的对象。
      5、对循环的优化
      尽量在for循环语句中将size或length等计算提取到循环外面,如下所示(对数组num{23,13,46,26,22,57}进行排序):
      int k = num.length;
      for(int i=0;i<k-1;i++)
      {
               for(int j=1;j<k;j++)
                  {
                        if(num[i]<=num[j])
                        {
                                   int temp = num[i];
                                   num[i] = num[j];
                                   num[j] = temp;
                        }
                  }
       }
优化的作用就是提高代码的执行效率,降低运行时的内存消耗,更好的适应各类内存类型的大小跟配置,以下内容将专门叙述有关代码优化的细节。
      A、除法运算优化
      在除法运算过程中使用移位操作比直接使用"/"更具效率,如(a+b)/2优化后的代码为(a+b)>>1。
      B、变量局部化
      在声明变量时候,尽量使用局部变量去替代全局变量,局部变量的赋值性能高于全局变量,如下代码:
      int sum;
      public void add(){
            for(int i=0;i<100;i++)
            sum += i;
      }
      优化后代码为:
      int sum;
      public void add(){
            int temp = sum;
            for(int i=0;i<100;i++)
            temp += i;
            sum = temp;
      }
      C、多选择switch
      在多选择情况下,使用switch进行判断而少用if-else来做判断,不但提高性能,而且提高代码可读性。
      D、字符串声明
      在字符串声明中,使用直接赋值比创建字符串对象好,比如String str = "test"; 比String str = new String("test");更节省内存,因为new本身创建了另一个字符串对象,从而增加了内存开销。
      E、字符串判空
      在判断一个字符串是否为空情况下,使用判断字符串长度是否为零,而不使用与""做比较,如使用str.length==0而不使用str.euqals("")。
      F、StringBuffer对象
      在使用StringBuffer中,如果操作一个字符,使用'',而不使用"",如'a',而不是"a"。
      G、异常处理优化
      在异常捕获处理代码中,可以使用对异常发生的情况先进行判断,并执行当异常情况请有效代码来替代try-catch的异常处理。如下代码:
      try{
            a.do();
      }catch(NullPointerException ex){
            //异常处理代码
      }
      优化为:
      if(a==null)
      {
             ruturn;  
       }else
       {
             a.do();
        }
      H、内部类
      使用内部类在某些时候带来一定好处,但是使用内部类会消耗更多的内存,因此尽量少使用内部类。
      I、程序暂停与开始
      在程序暂停pauseApp时候让无用的资源释放,而在开始startApp的时候获取资源,在程序停止destoryApp的时候释放所有资源。

posted on 2009-03-15 22:47 何双华 阅读(86) 评论(0)  编辑  收藏


只有注册用户登录后才能发表评论。


网站导航:
 
<2025年7月>
293012345
6789101112
13141516171819
20212223242526
272829303112
3456789

导航

统计

留言簿

文章档案

搜索

最新评论