AS3:优化对象内存大小

时间:2009-08-01 13:56:07

标签: actionscript-3 optimization memory-management class object

我有一个我写的课,它似乎比它应该更大。它没有扩展任何东西,并且很少发生 - 或者我认为 - 但是每个人都在 100k 100字节之下(感谢back2dos)。我想我不太了解对象在AS3中占用多少内存的真正原因。

如果有人能指点我阅读一些可能有用的主题,或者解释一下如何思考这个问题,那就太棒了。

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

感谢您的帮助。

编辑: 虽然我已按顺序完成此操作,但我保留了此处发布的代码,以确保完整性。该类已经从原始版本进行了大量修改。引用其他文件的值已经变为静态,以允许代码为其他人运行(理论上是hehehe ......)。

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

在这种情况下,该类有15个变量。我只使用一个字符串和一堆整数,数字和布尔值,并在全局可用的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;
        } 
    }
}

2 个答案:

答案 0 :(得分: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(对于bool)+ 4 * 11(对于整数)+4(对于字符串的引用)+ 8 * 3(对于三个)浮点数(你adder上的count + {8}表示空类(引用traits对象+其他东西),总共88个字节......这就是什么你得到的,如果你getSize对象...请注意,getSize只会给你对象本身的大小(这里计算)忽略你的字符串或其他对象的大小对象引用...

所以是的,除了这个名字你肯定应该改变,问题必须在其他地方......

格尔茨

back2dos

答案 1 :(得分:0)

如果你真的想节省空间,你可以通过使用无符号整数来伪造短路,并使用上/下位来做一件事。

int本质上是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个字节,使用数字而不是字符串更有意义。

另外,我相信你会通过将该类声明为final来实际获得一些内存增加,因为我相信最终函数会被放入traits对象,而不是