http://uh.9ria.com/space.php?uid=109929&do=blog&id=7306
上一篇我已介绍了一优化方法(上篇),这节我们继续.
位图优化
一般最占用内存的部分就是位图,在我开发的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强制内存回收方法之二》,而且受到大家的广泛关注,所以我不想让这篇文章误导了一些新手,以上只是个人见解我希望大家一起讨论这个问题).(上篇)
(此文为原创,如有雷同纯属缘分)