[url]http://uh.9ria.com/space-109929-do-blog-id-7267.html[/url]
内存优化在项目是一个重要的环节,如果不合理的利用和回收内存会合你的程序整体大大下降.
合理使用对象
创建不同对象一般所消耗的内存是不一样的。如: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,所以在高频率派发事件的地方你可以采用传统的回调函数这样可以大大提高你的效率和内存消耗.(下篇)
(此文为原创,如有雷同纯属缘分)
内存优化在项目是一个重要的环节,如果不合理的利用和回收内存会合你的程序整体大大下降.
合理使用对象
创建不同对象一般所消耗的内存是不一样的。如: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,所以在高频率派发事件的地方你可以采用传统的回调函数这样可以大大提高你的效率和内存消耗.(下篇)
(此文为原创,如有雷同纯属缘分)