Flash高性能开发基础系列—内存篇

合理使用

建不同象一般所消耗的内存是不一的。如:Number 消耗 8 个字,int消耗 4个字, uint消耗 4个字.下面我一些例子:

1.int 可使用表示 32 符号整数的数据型。 int 表示的的范是:-2,147,483,648 (-2^31)  2,147,483,647 (2^31-1),所以如果你的取-2,147,483,648 (-2^31)  2,147,483,647 (2^31-1)你用int而不是用Number(2.0转过来的人可能喜Number).uint  4,294,967,295 (2^32-1) ,Actionscript3型很少,所以些只要你平稍加注意一下就行.

2.合理使用ShapeSprite,MovieClip,你可能用MovieClip可以完成SpriteShape的功能,但是他所需的内存是不一Shape需要 236 ,Sprite 需要 412, MovieClip 需要440,如果你只想形没有交互那你使用Shape,如果是有交互的形你可以用Sprite,如果是画你才用MovieClip.

以上只是2个常例,其as3有很多得注意的这类情况。我看到有些大哥了派一个事件而去Sprite,Sprite需要消耗400, EventDispatcher只需要40.

象重用

简单就是重复使用象,而不是放再重新申,你可能认为放一个象回收100的空,我重新在new一个又占用100,返正都得占用100字。在flashplayer中不是你想放就能放的,垃圾回收是由flashplayer行的,程序是不能控制,更不知道他是什么候来行的.所以于我回来是完全不可控的.所以得可回收了象,很可能没回收继续占用空直到flashplayer得内存不够时才可能行垃圾回收从而被.行垃圾回收是非常耗费资源的操作尤其在大型的目中.

然我不能控制垃圾回收,但是我可以降低垃圾回收器行的次数,就是我尽量做到不去new,而使用有的象。些做有个好就是,省了象的性能开.

里是不断的

?View Code ACTIONSCRIPT

var size:Rectangle;
var bitmap:BitmapData=new BitmapData(100,100);
for (var:int = 0; i < 100; i++)
{

    size = new Rectangle(i,0,1,10);
    myBitmapData.fillRect(size,COLOR);
}

重用对象

<pre lang="actionscript">
var bitmap:BitmapData=new BitmapData(100,100);
var size:Rectangle = new Rectangle(0,0,1,10);
for (var:int = 0; i < 100; i++)
{
    size.x = i;
    myBitmapData.fillRect(size,COLOR);
}

象池技

象池技的原理就是回收不使用的象而不是弃等待FlashPlayer垃圾回器的,等到再需要再拿来使用.种技使用非常广泛,看下面的简单实现(里只是一个抛引玉,具体怎么设计这象池,要看各位的具体目了).

IRecyclable接口,可以被回收象必须实现。再就是ObjectPool.

?View Code ACTIONSCRIPT

package
{
    public interface IRecyclable
    {
   function dispose():void;
    }
}
//对象池的实现
package{
public class ObjectPool{

        private var pool:Vector.<IRecyclable>;
        private var type:Class;//回收对象的类型

   public function ObjectPool(type:Class)
       {
        this.type=type;
        pool=new Vector.<IRecyclable>();
        }
        public function addObject(o:IRecyclable):void{
        o.dispose();
        pool.push(o);
        }
        public function getObject():*{
        if(pool.length<=0) return new type();
             return pool.pop();
        }
    }
}

象的另

在存大量,我可以以另一种方式存或者叫序列化,即存储对象的数据而不存具体的象,当需要再根椐需要数据返序列化出一个象。这样做法的好在于不会有大量的生,在as即使是空象也会占用40个字.

很多候你可能这样写代:

?View Code ACTIONSCRIPT

var p:Array=[];

for(var i:int=0;i<1000000;i++){
    p.push(new Point(i,i))
}


里我来实现另一种象存:

?View Code ACTIONSCRIPT

package{
    import flash.geom.Point;

    public class PointContainer{

    private var container:Array
        public function PointContainer()
        {
        container=[];
        }
        public function add(v:Point):void{
        container.push(v.x);
        container.push(v.y);
        }
        public function getPointAt(index:int):Point{
       return new Point(container[index],container[index+1]);
        }
    }
}
//使用
var p:PointContainer=new PointContainer
for(var i:int=0;i<1000000;i++){
   p.add(new Point(i,i))
}
for(var i:int=0;i<1000000;i++){
   p.getPointAt(i);
}

象存 方式适合大量小型 象存 ,比如粒子系 . 如果是 大的 象, 种方式没有任何 .

事件

使用事件模型通信与使用传统的回函数相比,速度更慢且占用的内存更多

AS3中事件的派发传递参数是采用Event,所以在高率派事件的地方你可以采用传统的回函数这样可以大大提高你的效率和内存消耗.

图优

一般最占用内存的部分就是位,在我开MMO90%以上的的内存是由位占据的,所以在位的使用程序要特注意,不使用的位一定要放掉。在里我提一些小的建,以尽量控制位的内存占用。

1.能共享位的尽量共享,具体做法就是用一个BitampData建多个Bitamp象。尽量不要去复制BitmapData.

2.将滤镜应用于Flash Player 将在内存中建两个位,所以需要大量内存。所以尽量不要去使用滤镜,一般可以用ps做好滤镜后生成位图给flash来使用.

3.合理的使用位图缓.矢量形做位图缓存,其在把矢量成位,并使用

图进行呈,此会著提高呈的性能,但需要占用大量内存。针对的矢量内容使用位图缓存功能。

象其只有一句,就是不支有象的引用,包括声音/视频流,socket,件事等等.我最多的一种情况是事件忘移除象无法回收,并不是我不知道一点,而是在写代码时的疏忽。如果你是一个人开,你可能常去profile你的代,可能很容易找出哪个地方没被移除,但是如果你主程或者架构你手下有很多少人在Coding,你怎么他不忘移除事件呢,下面我来简单一种方法一次性移除所有事件,避免一个一个移除来的问题.

一般大家都用EventDispatcher来派事件.在我addEventListener行一个小小的改造即可.

?View Code ACTIONSCRIPT

package
{
    import flash.events.EventDispatcher;
    import flash.events.IEventDispatcher;

    public class MyEventDispatcher extends EventDispatcher{
        private var events:Array
        public function MyEventDispatcher(target:IEventDispatcher=null)
        {
        super(target);
        events=[];
        }
        override public function addEventListener(type:String, listener:Function, useCapture:Boolean=false, priority:int=0, useWeakReference:Boolean=false):void{

        events.push({type:type,fun:listener})
        super.addEventListener(type, listener, useCapture, priority, useWeakReference);
        }
        override public function removeEventListener (type:String, listener:Function, useCapture:Boolean = false):void{
             super. removeEventListener(type,listener, useCapture);
             for(var i:int=0;i< ;i++){
                 if( events[i].type==type && events[i].fun==listenner){
                 events.splice(i,1)
             }
        }
    }
        public function dispose():void{
        var ev:Object;
        while(events.length){
             ev=events.pop();
                super.removeEventListener(ev.type,ev.fun);
        }
        }
    }
}


所以你在使用
EventDispatcher 的地方全部使用 MyEventDispatcher 即可,在回收之前端 用一下 dispose 方法,就会内部移除所有事件 .

有很多方法可以做到一点,以上方法只是一个抛引玉.

制垃圾回收

Flashplayer debug版本提供了System.gc()接口,可以行垃圾回收,但是flashplayer 普通用版是没有个接口的,于是有人想出使用异常垃圾回收如:

?View Code ACTIONSCRIPT

function gc():void{
        try{
            (new LocalConnection).connect("foo");
                 (new LocalConnection).connect("foo");
       }catch(e){
                 trace(System.totalMemory);
            }
}

当然有其他方法在里我就不多.

Adobe什么在普通用版的flashplayer中取消System.gc()接口的支持,adobe肯定不希望用直接去触垃圾回器,肯定是有理由的,下面我将对这个理由行的浅薄分析.

垃圾回收器通过查找系中的相互引用,从而检测于非活象。将除通过这种方式检测到的于非活象。也就他要描可能持有象的的所有量,一点所需的代价很大,尤其是在大型目中.如果你常去做这样的事,会大大浪你的CPU.

我做Flash已快5年了,我没有什么地方非要用到制垃圾回收的地方.所以我要在里提醒广大Flash,在没有特需求的候不要使用制垃圾回收,不要会了出一点内存空而去制垃圾回收,可能很多候你是芝麻西瓜,回收器的行不是普通程序管的事,Flashplayer选择最合适的候去.(原本不是我要写的内容,原因是我看到在天地会主很醒目的位置有一篇《AS3制内存回收方法之二》,而且受到大家的广泛关注,所以我不想让这篇文章误导了一些新手,以上只是个人解我希望大家一起讨论这问题)



This is easy. You are creating Sprite, adding listeners, setting coordinates. The sprite is still empty. Then you set width and height, which are translating to scaleX and scaleY. On empty sprite this messes up transformation matrix and sprite will never show up. Set width, height, or scaleX/Y only on non-empty sprites.


为什么在Sprite中加入JPanelJAttachPane后再设置width,height就放大到非常大????

this.width = Config.getInstance().ISLAND_WIDTH; // 720

this.height = Config.getInstance().ISLAND_HEIGHT; // 620

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值