【问题标题】:AS3: Optimizing Object Memory SizeAS3:优化对象内存大小
【发布时间】:2009-08-01 13:56:06
【问题描述】:

我有一个我写的类,它看起来比它应该的要大。它没有扩展任何东西,并且几乎没有发生什么 - 或者我认为 - 但每个都占用不到 100k100 字节(感谢 back2dos )。我想我对真正影响 AS3 中对象占用多少内存的因素没有很好的理解。

如果有人能指出一些关于该主题的阅读材料可能会有所帮助,或者解释一些关于如何思考这个问题的见解,那就太棒了。

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

感谢您的帮助。

编辑: 虽然我已经整理好了,但为了完整起见,我保留了我在此处发布的代码。该类已从原始版本进行了大量修改。引用其他文件的值已设为静态,以允许代码为其他人运行(理论上嘿嘿嘿...)。

虽然我的情况已经整理好了,但我还是给个不错的参考答案吧,关于类和内存的信息。

在这种情况下,该类有 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;
        } 
    }
}

【问题讨论】:

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


    【解决方案1】:

    我很惊讶,这完全可以编译......当我尝试使用 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(对于三个浮动(addercount 上的某个位置)+ 8 用于空类(对特征对象的引用+其他东西),总共给你 88 个字节......也就是说,你得到什么,如果您 getSize 对象...但是请注意,getSize 只会为您提供对象本身的大小(在此处计算),而忽略对象引用的字符串或其他对象的大小...

    所以是的,除了你肯定应该更改的那个名字之外,问题一定出在其他地方......

    问候

    back2dos

    【讨论】:

    • 我为帖子重命名了东西,这不是我的确切代码。我改变了那个。我还在这里将一些依赖于其他文件的变量更改为固定值,这导致了你看到的很多奇怪之处。当我运行 Flex 分析器时,我现在运行它时得到大约 12000。我想我假设正在使用的内存是 Kb no b,因为内存监视器正在跟踪 kb。嗯......所以我想事情是有序的,我误读了我在这种情况下看到的内容。谢谢你让我理顺。我已经更新了帖子,说明代码已被修改。
    【解决方案2】:

    如果你真的想节省空间,你可以通过使用无符号整数来伪造短裤,并为一件事或另一件事使用高位/低位。

    整数本质上是 4 个字节,您可以在小于 2^8 的任何内容上重复使用该整数。

    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 会增加一些内存,因为我相信 final 函数会被放入特征对象中,而不是

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-11-01
      • 1970-01-01
      • 2016-09-17
      • 2019-08-23
      • 2022-11-29
      • 2013-11-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多