[转] Flash高性能开发基础系列 ― 内存篇【下】

本文分享了位图优化的经验,提出了共享位图、合理使用缓存等建议,避免内存占用过高,提升游戏性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

[url]http://uh.9ria.com/space.php?uid=109929&do=blog&id=7306[/url]

上一篇我已介绍了一优化方法(上篇),这节我们继续.
位图优化
一般最占用内存的部分就是位图,在我开发的MMO游戏中90%以上的的内存是由位图占据的,所以在位图的使用过程序要特别注意,不使用的位图一定要释放掉。在这里我提一些小的建议,以尽量控制位图的内存占用。

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

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

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

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

释放对象
释放对象其实只有一句话,就是不支有对象的引用,包括声音/视频流,socket,件事等等.我最多的一种情况是事件忘记移除导致对象无法回收,这并不是我不知道这一点,而是在写代码时的疏忽。如果你是一个人开发,你可能经常去profile你的代码,可能很容易找出哪个地方没被移除,但是如果你主程或者架构师你手下有很多少人在Coding,你怎么让他不遗忘移除事件呢,下面我来简单介绍一种方法一次性移除所有事件,避免一个一个移除带来的遗漏问题.
一般大家都用EventDispatcher来派发事件.现在我们就对addEventListener进行一个小小的改造即可.
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 普通用户版是没有这个接口的,于是有人想出使用异常还出发垃圾回收如:
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强制内存回收方法之二》,而且受到大家的广泛关注,所以我不想让这篇文章误导了一些新手,以上只是个人见解我希望大家一起讨论这个问题).(上篇)
(此文为原创,如有雷同纯属缘分)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值