AS3:优化对象内存大小

问题描述:

我有一门我写的类,看起来比它应该大。它没有扩展任何东西,并且几乎没有发生 - 或者我想 - 但是每个都占用了 100k 100字节(感谢back2dos)。我想我没有很好的理解什么会影响AS3中对象占用多少内存。AS3:优化对象内存大小

如果任何人都可以指出我对这个主题的一些阅读可能有帮助,或者可以解释一些关于如何思考这个问题的见解,那就太棒了。

我想保留很多这些对象在内存中 - 我想我可以直到现在,但在这个大小,我将不得不创建它们或使用某种对象池技术。

感谢您的协助。

编辑:虽然我为了得到这个,我保持我这里张贴的完整性的代码。该课程已经从原始版本进行了大量修改。引用其他文件的值已被设置为静态,以允许代码为其他人运行(理论上hehehe ...)。

虽然我的情况已经解决,但我会给出有关类和内存信息的良好参考的答案。

在这种情况下,该类有15个变量。我只使用单个字符串和一系列整数,Numbers和布尔值,并在全局可用的XML数据中引用更多相同的内容。它还为构造函数导入Point,但不存储点。在测试中,即使没有全局XML引用或Point类,它仍然约为84k。除了构造函数外,还有7个变量的getter和一些方法。所有这些都不到20行(我有一个非常稀疏的编码风格)。

参考提到的类,但随时来概括:

package 
{ 
    public class AObject 
    { 
     private var _counter:int; 
     private var _frames:int; 
     private var _speed:int; 

     private var _currentState:String; 
     private var _currentFrame:int; 

     private var _offset:int; 
     private var _endFrame:int; 

     private var _type:int; 
     private var _object:int; 
     private var _state:int; 

     private var _x:Number; 
     private var _y:Number; 

     private var _w:int; 
     private var _h:int; 

     private var _update:Boolean; 

     public function AObject(targetX : int, targetY : int, state : int, object : int, type : int) 
     {  

      _x = targetX; 
      _y = targetY; 

      _type = type; 
      _object = object; 
      _state = state; 
      _counter = 0; 
      _w = 32; 
      _h = 32 
      _update = true; 
      setState(state); 
     } 

     public function setState(state:int) : void 
     { 
      _currentState = "bob"; 
      var frameCounter : int = 0; 
      var stateCounter : int = state - 1; 
      while (state > 0) 
      { 
       frameCounter += 4; 
       --stateCounter; 
      } 
      _offset = frameCounter; 
      _currentFrame = _offset; 
      _speed = 10; 
      _frames = 4; 
      _endFrame = _offset + _frames - 1; 
     } 

     public function get state() : int 
     { 
      return _state; 
     } 

     public function animate() : Boolean 
     { 
      if (count()) 
      { 
       if(_currentFrame < _endFrame) 
       { 
        ++_currentFrame; 
       } 
       else 
       { 
        _currentFrame = _offset;  
       } 
       _speed = 10; 
       return true; 
      } 
      else 
      { 
       return false; 
      } 
     } 

     private var adder: Number = 0; 

     private function count():Boolean 
     { 
      _counter++; 
      if (_counter == _speed) 
      { 
       _counter = 0; 
       return true; 
      } 
      else 
      { 
       return false; 
      } 
     } 

     public function get x():int 
     { 
      return _x; 
     } 

     public function get y():int 
     { 
      return _y; 
     } 

     public function get type():int 
     { 
      return _type; 
     } 

     public function get object():int 
     { 
      return _object; 
     } 

     public function get currentFrame():int 
     { 
      return _currentFrame; 
     } 

     public function get w():int 
     { 
      return _w; 
     } 

     public function get h():int 
     { 
      return _h; 
     } 
    } 
} 

我很惊讶,这个编译在所有...当我尝试使用Flex SDK编译它,它创建了一个巨大的碰撞与内置的类Object,这是任何类的基类,使我的跟踪输出溢出...

除此之外,这是一个无限循环,如果你通过一个值大于0的状态

while (state > 0) 
{ 
     frameCounter += 4; 
     --stateCounter; 
} 

但似乎真的很奇怪这些对象都这么大了......重命名和注意不要在0传递的状态后,我跑了个试验:

package { 
    import flash.display.Sprite; 
    import flash.sampler.getSize; 
    import flash.system.System; 
    public class Main extends Sprite { 
     public function Main():void { 
      const count:int = 100000; 
      var start:uint = System.totalMemory; 
      var a:Array = []; 
      for (var i:int = 0; i < count; i++) { 
       a.push(new MyObject(1, 2, 0, 4, 5)); 
      } 
      var mem:uint = System.totalMemory - start - getSize(a); 
      trace("total of "+mem+" B for "+count+" objects, aprox. avg. size per object: "+(mem/count)); 
     }  
    } 
} 

它产生:

total of 10982744 B for 100000 objects, aprox. avg. size per object: 109.82744 

所以这是相当好的...我认为实际大小应该是4(对于布尔)+ 4 * 11(对于整数)+4(对于字符串的参考)+ 8 * 3(对于三个浮点数你有adder某处在count)+8的空类(引用traits对象+别的东西),给你总共88字节......这就是说,w你得到的帽子,如果你getSize的对象... ... - 但是请注意,getSize只会给你的对象本身的大小(如下计算)忽略了什么字符串或其他对象的对象引用的大小...

所以是的,除了这个名字你一定要变化,这个问题必须在别处......

格尔茨

back2dos

+0

我改名的东西的职位,这不是我的确切码。我改变了这一点。我还将一些依赖于其他文件的变量更改为固定值,这些变量说明了您看到的很多奇怪现象。 当我运行Flex Profiler时,当我运行它时,我获得了约12000个。我想我假设正在使用的内存是Kb无b,因为内存监视器正在跟踪kb。嗯......所以我猜想事情是有序的,而且我误解了在这种情况下我所看到的。感谢您的理解。我已更新帖子以注意代码已被修改。 – grey 2009-08-01 18:49:06

如果你真的想节省空间,可以假短裤采用无符号整数,并使用上/下位的一件事或另一件事。

ints本质上是4个字节,您可以在小于2^8的任何东西上重用该int。当你想要写什么或读什么

width height 
0xFFFF + 0xFFFF 

offset endframe 
0xFFFF + 0xFFFF 

这虽然变得难看,因为编写的宽度和高度,你不得不:

writing: 
size = (width & 0x0000FFFF) << 16 | (height & 0x0000FFFF); 

reading: 
get width():uint { return (size & 0xFFFF0000) >> 16 }; 

这是丑陋的。既然你使用getter,并且假设计算速度不是问题,那么你可以使用内部字节数组,这可以使你更加精确地存储你的信息。假设你的字符串超过4个字节,使用数字而不是字符串更有意义。

而且,我相信你会真正通过声明类作为最终得到一些内存的增加,我相信最终的功能得到安置到traits对象,而不是