内存优化在项目是一个重要的环节,如果不合理的利用和回收内存会合你的程序整体大大下降
.
合理使用对象
创建不同对象一般所消耗的内存是不一样的。如
: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
范围是
0
到
4,294,967,295 (2^32-1)
之间
,Actionscript3
中类型很少,所以这些只要你平时稍加注意一下就行
.
2.
合理使用
Shape
与
Sprite,MovieClip,
你可能用
MovieClip
可以完成
Sprite
与
Shape
的功能,但是他们所需的内存是不一样的
Shape
需要
236
字节
,Sprite
需要
412
字节
, MovieClip
需要
440
字节
,
如果你只想显示图形没有交互那你使用
Shape,
如果是有交互的图形你可以用
Sprite,
如果是动画你才用
MovieClip.
以上只是
2
个常见的实例,其实在
as3
中还有很多值得注意的这类情况。我还看到有些大哥为了派发一个事件而去继承
Sprite
类
,Sprite
需要消耗
400
字节
,
EventDispatcher
只需要40
字节.
对象重用
简单的说就是重复使用对象,而不是释放再重新申请
,
你可能这么认为:释放一个对象回收
100
字节的空间,我重新在
new
一个又占用
100
字节,返正都得占用
100
字。在
flashplayer
中不是说你想释放就能释放的
,
垃圾回收是由
flashplayer
来执行的,程序是不能控制,更不知道他是什么时候来执行的
.
所以对于我们来说回来是完全不可控的
.
所以说你觉得可回收了对象,很可能没回收继续占用空间直到
flashplayer
觉得内存不够时才可能执行垃圾回收从而被释放
.
而执行垃圾回收是非常耗费资源的操作尤其在大型的项目中
.
虽然我们不能控制垃圾回收,但是我们可以降低垃圾回收器执行的次数,这就是我们尽量做到不去
new,
而使用现有的对象。这些做还有个好处就是,节省了创建对象的性能开销
.
这里是不断的创建对象
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);
}
重用对象
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.
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
个字节
.
很多时候你可能这样写代码
:
var
p:Array=[];
for
(
var
i:int=0;i<1000000;i++){
p.push(
new
Point(i,i))
}
这里我来实现另一种对象存储
:
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,
所以在高频率派发事件的地方你可以采用传统的回调函数这样可以大大提高你的效率和内存消耗
.
位图优化
一般最占用内存的部分就是位图
,
在我开发的
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
强制内存回收方法之二》
,
而且受到大家的广泛关注
,
所以我不想让这篇文章误导了一些新手
,
以上只是个人见解我希望大家一起讨论这个问题
).
转自:http://uh.9ria.com/space.php?uid=109929&do=blog&id=7267
分享到:
相关推荐
《Flash高级开发指南》是专为高级开发者设计的详尽指南,由Rex van der Spuy撰写,旨在深入探讨游戏设计中的高级技术和策略。本书涵盖了游戏设计师必须掌握的所有关键技术,包括游戏物理、寻路算法、模型-视图-控制...
在Adobe Flash平台上开发应用时,性能优化是提升用户体验的关键因素。Flash因其强大的交互性和跨平台能力,曾广泛应用于网页游戏、动画以及丰富的互联网应用程序(RIA)。然而,随着技术的发展,Flash面临性能挑战,...
在IT行业中,Flash游戏开发是一项历史悠久的技术,尤其在互联网初期,Flash因其强大的动画制作和交互功能,成为游戏开发者们的首选工具。本教程“Flash游戏开发教程”旨在引导初学者掌握如何利用Flash进行游戏制作,...
知识点:使用Flash Builder开发iOS应用 一、Adobe AIR在iOS上的性能提升 Adobe AIR,作为Adobe公司的跨平台运行环境,自版本2.6起,在iOS设备上的性能得到了显著提升。这些改进包括: - BitmapCapture in ...
Pulse SDK提供了高性能的网络通信解决方案,包括GNet CPU集群服务,确保了游戏在网络环境下的稳定性和流畅度。这种技术的支持使得游戏可以支持更多的在线玩家,并且保持良好的用户体验。 ##### 3. 易于集成与使用 ...
- **Monocle**:一款用于创建高性能OpenGL ES 2.0 3D渲染的框架。 #### 为什么选择Flash进行移动应用开发? - **后PC时代**:随着移动设备的普及,智能手机已经成为人们在线活动的主要入口。因此,跨屏幕的应用...
在实际的ARM开发板上进行实验,经过以上流程开发的驱动程序,能够在保持代码小巧的同时,实现高性能的闪存操作,从而满足嵌入式系统的需求。 总之,Nor Flash和Nand Flash的接口设计和驱动开发涉及硬件特性的理解、...
FlashDevelop是一款免费、开源的集成开发环境(IDE),专门用于创建使用ActionScript和Flex技术的Flash...无论你是初学者还是资深开发者,FlashDevelop都能提供你需要的工具和环境,助力你开发出高质量的Flash内容。
ActionScript 3.0是Flash Player支持的最新版本,它带来了许多性能上的改进,包括类的面向对象编程、错误处理机制和类型检查。在游戏开发中,ActionScript可以用于创建游戏对象(如角色、敌人、道具等),实现碰撞...
在开发Flash播放器的过程中,你需要深入理解VC++(Visual C++)编程,因为它是构建桌面应用程序的常用工具,尤其适用于创建高性能的多媒体软件。Flash播放器的开发涉及到多个技术层面,包括ActionScript的理解、SWF...
AS3中的Stage3D API是处理3D图形的关键,它允许开发者直接与GPU进行交互,实现高性能的3D渲染。 - ** Away3D 和 Papervision3D**:在Flash 3D领域,Away3D和Papervision3D是两个广泛使用的开源库。它们为开发者提供...
这对于游戏开发尤其关键,因为高帧率能提供更流畅的游戏体验。 在使用Adobe Scout CC时,用户可以设置不同的监控级别,从基本的CPU和内存使用情况到详细的代码剖析。这使得开发者可以根据自己的需求定制分析深度。...
《Flash高级动画教程》是一门深入探讨Flex开发技术和Flash高级应用的课程,旨在帮助游戏开发者以及其他视觉内容创作者提升他们的技能,使他们能够更好地理解和运用ActionScript 3.0来创建复杂的交互式动画和游戏。...
C++以其高效、灵活和强大的功能被广泛应用于游戏开发,尤其是大型游戏的后端服务和高性能计算部分。C++可以直接操作硬件,实现更低级别的控制,对于游戏中的实时性要求和性能优化非常关键。 【FLASH Socket】 Flash...
Flash Develop是一款专为创建基于Flash平台的项目而设计的免费、开源集成开发环境(IDE)。它支持ActionScript 2和3、Haxe以及AS3 Flex框架的开发,为游戏、动画以及其他互动内容的制作提供了强大的工具。这款IDE以...
在IT领域,尤其是在游戏开发、互动媒体设计以及网络应用程序中,Adobe Flash因其强大的动画和交互功能而被广泛使用。然而,随着技术的发展,Flash的性能优化成为了一个关键议题,因为性能不佳可能导致用户体验下降,...
《Flash CS4高级开发教程》是一本针对Adobe Flash Professional CS4这一强大动画和交互式内容创作工具的专业指南。本教程全面覆盖了Flash CS4的高级功能和开发技术,旨在帮助用户提升技能,从初级创作者晋升为能够...
本书结合Web 2.0以来Web开发领域的最新形势和特点,介绍了网站性能问题的现状、产生的原因,以及改善或解决性能问题的原则、...《高性能网站建设指南》适合Web架构师、信息架构师、Web开发人员及产品经理阅读和参考。