2009-08-01 118 views
1

我有一門我寫的類,看起來比它應該大。它沒有擴展任何東西,並且幾乎沒有發生 - 或者我想 - 但是每個都佔用了 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; 
     } 
    } 
} 

回答

3

我很驚訝,這個編譯在所有...當我嘗試使用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

0

如果你真的想節省空間,可以假短褲採用無符號整數,並使用上/下位的一件事或另一件事。

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對象,而不是