CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
不看会后悔的Windows XP之经验谈 简单快捷DIY实用家庭影院
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  Java >  J2ME

节约内存的小技巧——数据打包

楼主midamia(戒骄戒躁,不忘本色)2003-12-03 00:02:35 在 Java / J2ME 提问

说实话,技巧太小。  
  现在,你的任务是设计一个《大富翁》。地图上有50块地,我们不妨定义一个Field类。它应该有哪些数据成员呢?一个可能的设计是:  
  int   x_player;                     //人的占位  
  int   y_player;  
  int   x_house;                       //房子的占位  
  int   y_house;  
  int   price;                               //地价  
  int   houseType;                       //建筑物  
  int   owner;                               //所有者   0表示空地  
  int   state;                               //状态    
  就这样吧,也许不合适,但这只是个例子,每一块地需要32个字节。  
   
  然后我们来看,如果整张地图的大小是250*250,那么一个坐标就没有必要用4个字节,1个足够;我们可以进行第一步改进:  
  byte   x_player;  
  byte   y_player;  
  byte   x_house;  
  byte   y_house;  
  int   price;  
  byte   houseType;  
  byte   owner;  
  byte   state;  
  一共占用11个字节。  
   
  接着,考虑到房子相对于人的方位只有4种(左上、左下、右上、右下),而且只要方位相同,坐标差就相同,这样只要2位足以保存房子的坐标;  
  考虑到地价不会超过999999(最贵的商业街,最顶级的房子,而且地价临时上涨的情况),那么price需要20位;  
  建筑物只有3级,需要2位;  
  npc人物有6个,owner需要3位;  
  state无非正常、地价上涨、地价下跌、被查封4种情况,需要2位。  
   
  于是新的设计如下:  
  //保存4种情况下,房子和角色的坐标差  
  static   final   byte[]   instance=new   byte[]{dx1,dy1,dx2,dy2,dx3,dy3,dx4,dy4};  
  byte   x_player;  
  byte   y_player;  
  int   otherValue;//在这32位中,housePosition占2位,houseType占2位,npcId占3  
                                //位,state占2位,price占20位,剩余3位,你还可以定义其他属性  
  一共占用6个字节。  
   
  你可以联合使用逻辑操作和移位操作存取你打包的数据。  
  当然缺点也是不言而喻的,实际上并不总是这样精打细算,但总会有需要精打细算的时候。  
  这里只有50片地,如果是2000支股票,50000个客户信息呢? 问题点数:0、回复次数:12Top

1 楼midamia(戒骄戒躁,不忘本色)回复于 2003-12-03 00:06:10 得分 0

抛砖引玉,希望大家都来介绍介绍自己的心得Top

2 楼mercuryking(时间空间)回复于 2003-12-03 08:21:48 得分 0

很强!Top

3 楼ludingping(http://blog.csdn.net/ludingping)回复于 2003-12-03 08:33:02 得分 0

很好。让我认识到凡事只要有心,就可以做到精益求精Top

4 楼sunny110(沙漠)回复于 2003-12-03 09:01:17 得分 0

学习Top

5 楼huowenfeng(痛苦来源于对小概率事件的不懈追求)回复于 2003-12-03 09:07:08 得分 0

pretty   boy.Top

6 楼AOM(spaces.msn.com/aom7610)回复于 2003-12-03 10:21:26 得分 0

有搞头!  
  Top

7 楼jax(阿杰)回复于 2003-12-03 10:35:05 得分 0

真的不错,不过这里还是有必要同时考虑运行的速度和编程效率问题Top

8 楼midamia(戒骄戒躁,不忘本色)回复于 2003-12-03 10:41:37 得分 0

昨天太晚,没有写晚,下面的部分更精彩。  
  对于50片地,通常的做法是:  
  class   GameFullCanvas   extends   FullCanvas{  
      private   Field[]   fields   =   new   Field[50];//当然,还需要对每一个成员初始化  
  //以下略  
  }  
  但我们知道,每一个对象都要占用额外的内存空间(如一些指向函数的指针),大量的数据应该使用基本数组,而不是对象数组来维护。同时,数据在打包的情况下读写很麻烦,给维护和测试带来很多不便。  
  这种情况,有的人会放弃对象思想,完全使用数组,把java当c语言来用。就像这样:  
  class   GameFullCanvas   extends   FullCanvas{  
      static   final   byte[]   instance   =   new   byte[]{dx1,dy1,dx2,dy2,dx3,dy3,dx4,dy4};  
      static   final   byte[]   x_player;  
      static   final   byte[]   y_player;  
      staitc   int[]   otherValue;  
      //以下略  
  }  
  这样一来Field类就没有存在的必要了,原本Field类中的方法都可以放在GameFullCanvas里,并且以j2me游戏设计是面向屏幕的,而不是面向对象的为其理论基础。而且这并没有解决打包数据读取不变的问题。  
  在传统面向对象思想不可用的情况下,如何变通是摆在我们每一个j2me程序员面前的课题。  
  我的解决方案如下:  
  class   Field{  
      static   final   byte[]   instance   =   new   byte[]{dx1,dy1,dx2,dy2,dx3,dy3,dx4,dy4};  
      static   final   byte[]   x_player;//需初始化,以下同  
      static   final   byte[]   y_player;  
      static   int[]   otherValue;  
   
  //都定义成int也无妨了,就奢侈一点吧  
      private   int   fieldId;  
      private   int   x_Player;  
      private   int   y_Player;  
      private   int   x_House;  
      private   int   y_House;  
      private   int   price;  
      private   int   houseType;  
      private   int   npcId;  
      private   int   state;  
   
      public   init(int   id){  
          fieldId   =   id;  
          x_Player   =   x_player[id];  
          y_Player   =   y_player[id];  
          //所有打包数据解包,并保存在相应变量中  
          //可能还有其他初始化代码  
      }  
   
      public   pack(){  
      //在这里所有成员变量打包,保存进静态数组  
      }  
  //省略其他方法  
  }  
  如何使用这个Field类呢?请看:  
  class   GameFullCanvas   extends   FullCanvas{  
      private   Field   field   =   new   Field();  
       
      private   someFunction(){  
          field.init(fieldId);  
          field.someFunction();  
          //如果数据发生改变,就打包保存,也可以由field自己决定是否保存  
          field.pack();  
      }  
  //以下略  
  }  
  这样,虽然地有50片,但是Field类的实例只有一个,并且被反复重用。不知这个技巧是编码的技巧,还是设计的技巧?  
  最后,希望我的文章对大家有帮助。Top

9 楼jigsaw(echo)回复于 2003-12-03 11:11:08 得分 0

en...楼主很强,佩服。  
   
  我就是抛不掉以前的思路,抛不掉OO的影响。  
  说实话,我每当在midp里面要用到anti-OO的代码的时候,  
  自己都会加个注释://ugly    
  呵呵  
  写了1年了   还是这种思想   也许我不适合做条件受限的手机端编程吧。=(  
  不过无所谓了   找机会跳就是了Top

10 楼starpan()回复于 2003-12-03 11:16:13 得分 0

定义的包装载不了,是什么原因?出现的错误是Cannot   access   directory   s   at   line   12;请问这是为什么?是不是我定义的时候出错了,还是调用的时候,还是把包中的类摆放的位置不对呢?  
  Top

11 楼TODER(TOD)回复于 2003-12-04 00:29:34 得分 0

楼主很强,佩服!佩服!从中学到了不少的知识。了解了j2me的一些解决问题的办法,谢了!Top

12 楼ziyue(紫月)回复于 2004-02-10 09:48:17 得分 0

我还以为什么新的方法。Top

相关问题

  • 打包,打包???
  • C++的风格与技巧(6) - 内存堆的释放
  • 打包
  • 打包
  • 打包
  • 打包
  • 打包!~~~
  • 打包
  • 突然想到的一个节约内存的问题,大家帮我看看这个想法对不对
  • 要开发一个Pocket PC上面的图片文件浏览程序,关于如何节约内存的问题?

关键词

  • j2me
  • player
  • 数据
  • 坐标
  • 打包
  • dy
  • dx
  • 地价
  • 数组
  • gamefullcanvas

得分解答快速导航

  • 帖主:midamia

相关链接

  • CSDN Java频道
  • Java类图书
  • Java类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
世纪乐知(北京)网络技术有限公司 版权所有, 京 ICP 证 020026 号
北京创新乐知广告有限公司 提供技术支持
Copyright © 2000-2007, CSDN.NET, All Rights Reserved
GongshangLogo