AS3游戏中可视对象上限及位图相干的内存耗损实测

前些天持续做了一些测试,以减深对AS3的┞菲握战正在项目中洞课戏机能、效率劣化圆里的一些处理,有许多测试实践意义没有年夜,皆不外是证实一些猜念是正确的,除此出有甚么。

但前天停止的一戏诵测试中,有一些洞课戏开发中的内存占趺,CPU占趺圆里又供意义,我筹算逐步写几篇会商性的文┞仿取各人同享。
因为最远正在做的是2D的等距视角游辖爆局部接纳的位图处理,取3D无闭,以是存眷的也是那圆里的问题,思索问题的动身面也是那些圆里,因而存眷里仍是比力狭小的。

  1、先从那类2D游戏中经常使用的对象类型的简单测试去开端看AS3的蹬鲢是如何撑持
那只能是管窥一斑,我也只能是据囱碰面推测,至于AS3蹬鲢到底如何完成,年夜可没必要来弄的很分明,但测试的成果仍由以正在我们写代码时,做到胸有定见。

先去看测试函数代码private function compareDisplayObject():void
{
        len1 = System.totalMemory;
        _txt.text = "测试前总内存巨细为:" + len1.toString();
        
        var sprite:Sprite = new Sprite();
        len2 = System.totalMemory;
        _txt.appendText("\nnew Sprite后总内存巨细为:" + len2.toString());
        _txt.appendText("\nnew Sprite后增长的内存为:" + (len2 - len1).toString());
        
        var bmp:Bitmap = new Bitmap();
        len1 = System.totalMemory;
        _txt.appendText("\n\nnew Bitmap后总内存巨细为:" + len1.toString());
        _txt.appendText("\nnew Bitmap后增长的内存为:" + (len1 - len2).toString());
        
        var shape:Shape = new Shape();
        len2 = System.totalMemory;
        _txt.appendText("\n\nnew Shape后总内存巨细为:" + len2.toString());
        _txt.appendText("\nnew Shape后增长的内存为:" + (len2 - len1).toString());
        
        var rect:Rectangle = new Rectangle(0, 0, 200, 100);
        len1 = System.totalMemory;
        _txt.appendText("\n\nnew Rectangle,巨细为200*100后总内存巨细为:" + len1.toString());
        _txt.appendText("\nnew Rectangle,巨细为200*100后增长的内存为:" + (len1 - len2).toString());
        
        //正文失落上面冶,零丁测试将sprite、bmp、shape三个空对象加减到隐示列表。
        sprite.graphics.drawRect(0, 0, 200,100);
        len2 = System.totalMemory;
        _txt.appendText("\n\nsprite画造200*100的矩形后总内存巨细为:" + len2.toString());
        _txt.appendText("\nsprite画造200*100的矩形后增长的内存为:" + (len2 - len1).toString());
        shape.graphics.drawRect(0,0,200,100)
        len1 = System.totalMemory;
        _txt.appendText("\n\nshape画造200*100的矩形后总内存巨细为:" + len1.toString());
        _txt.appendText("\nshape画造200*100的矩形后增长的内存为:" + (len1 - len2).toString());
        
        this.addChild(sprite);
        len2 = System.totalMemory;
        _txt.appendText("\n\n将sprite加减到舞台后总内存巨细为:" + len2.toString());
        _txt.appendText("\nsprite加减到舞台后增长的内存为:" + (len2 - len1).toString());
        this.addChild(bmp);
        len1 = System.totalMemory;
        _txt.appendText("\n\n将bmp加减到舞台后总内存巨细为:" + len1.toString());
        _txt.appendText("\nbmp加减到舞台后增长的内存为:" + (len1 - len2).toString());
        this.addChild(shape);
        len2 = System.totalMemory;
        _txt.appendText("\n\n将shape加减到舞台后总内存巨细为:" + len2.toString());
        _txt.appendText("\nshape加减到舞台后增长的内存为:" + (len2 - len1).toString());
}
 

转载注明盛世游戏:http://www.shengshiyouxi.com 

再去看输出成果:
//------------------------------------------------>
  测试前总内存巨细为:3162112
new Sprite后总内存巨细为:3162112
new Sprite后增长的内存为:0

new Bitmap后总内存巨细为:3162112
new Bitmap后增长的内存为:0

new Shape后总内存巨细为:3170304
new Shape后增长的内存为:8192

new Rectangle,巨细为200*100后总内存巨细为:3182592
new Rectangle,巨细为200*100后增长的内存为:12288

sprite画造200*100的矩形后总内存巨细为:3190784
sprite画造200*100的矩形后增长的内存为:8192

shape画造200*100的矩形后总内存巨细为:3198976
shape画造200*100的矩形后增长的内存为:8192

将sprite加减到舞台后总内存巨细为:3207168
sprite加减到舞台后增长的内存为:8192

将bmp加减到舞台后总内存巨细为:3211264
bmp加减到舞台后增长的内存为:4096

将shape加减到舞台后总内存巨细为:3215360
shape加减到舞台后增长的内存为:4096
  [color=ize:13px]//------------------------------------------------>
  前天测试时,每次运转FP,第一次根本上new Sprite,Bitmap,Shape后增长的内存皆没有为0,前两者皆是4096,Shape是8192,但明天每次从头运转前里两个对象new 后内存增长皆是0。

运转当前,屡次挪用那个函数,输出的内容能够看到内存每次反复挪用时皆正在之前根底梢减,但那寂new 操做以后,内存的增长经常0,而Shape为0的时分很少,大都是4096,偶然是8192。

我推测,那该当实了止时环境以为new 出去的式昌,出有利用,而且援用计数也是0,以是被收受接管了,那从输出内容的前面一些部门(对象被加减到隐示列表中),所隐示的内存增长一直年夜于0能够看出去。

可是重复挪用那个函数时,将sprite式昌加减到隐示列表中,使得增长的内村却经常正在4096战8192之间变更,那让我感应很是疑惑,念没有到公道的解释。

  2、对sprite,bitmap,shape  new 一批空对象,及将一批空对象加减到隐示列表的内存占趺测试
那里说的空对象没有是指null的无值状况,而是仅指new以后,没有减任那边理或赋值的状况。

先去看测试代码:private function compareMultiDisplayObject():void
{
        //每类对象new的个数
        var num:uint = 1000;                        
        
        len1 = System.totalMemory;
        _txt.text = "每匆汛建" + num.toString() + "个同类对象,测试前总内存巨细为:" + len1.toString();
        
        var i:uint;
        var sprite:Sprite;
        var bmp:Bitmap;
        var shape:Shape;
        
        for (i = 0; i < num; i++)
        {
                sprite = new Sprite();
               
                //恢复以下正文,让new出去的对象有援用计数,躲免对象被以为无利用而被收受接管
                //arr.push(sprite);
        }
        len2 = System.totalMemory;
        _txt.appendText("\nnew Sprite后总内存巨细为:" + len2.toString());
        _txt.appendText("\nnew Sprite后增长的内存为:" + (len2 - len1).toString() + " || 均匀每一个增长:" + ((len2 - len1)/num).toString());
        
        
        for (i = 0; i < num; i++)
        {
                bmp = new Bitmap();
                //arr.push(bmp);
        }                        
        len1 = System.totalMemory;
        _txt.appendText("\n\nnew Bitmap后总内存巨细为:" + len1.toString());
        _txt.appendText("\nnew Bitmap后增长的内存为:" + (len1 - len2).toString() + " || 均匀每一个增长:" + ((len1 - len2)/num).toString());
        
        for (i = 0; i < num; i++)
        {
                shape = new Shape();
                //arr.push(shape);
        }                        
        len2 = System.totalMemory;
        _txt.appendText("\n\nnew Shape后总内存巨细为:" + len2.toString());
        _txt.appendText("\nnew Shape后增长的内存为:" + (len2 - len1).toString() + " || 均匀每一个增长:" + ((len2 - len1)/num).toString());
        
        _txt.appendText("\n\n================以下为创立并加减到隐示列表================");
        
        for (i = 0; i < num; i++)
        {
                sprite = new Sprite();
                this.addChild(sprite);
        }
        len1 = System.totalMemory;
        _txt.appendText("\nnew Sprite后总内存巨细为:" + len1.toString());
        _txt.appendText("\nnew Sprite后增长的内存为:" + (len1 - len2).toString() + " || 均匀每一个增长:" + ((len1 - len2)/num).toString());
        
        
        for (i = 0; i < num; i++)
        {
                bmp = new Bitmap();
                this.addChild(bmp);
        }                        
        len2 = System.totalMemory;
        _txt.appendText("\n\nnew Bitmap后总内存巨细为:" + len2.toString());
        _txt.appendText("\nnew Bitmap后增长的内存为:" + (len2 - len1).toString() + " || 均匀每一个增长:" + ((len2 - len1)/num).toString());
        
        for (i = 0; i < num; i++)
        {
                shape = new Shape();
                this.addChild(shape);
        }                        
        len1 = System.totalMemory;
        _txt.appendText("\n\nnew Shape后总内存巨细为:" + len1.toString());
        _txt.appendText("\nnew Shape后增长的内存为:" + (len1 - len2).toString() + " || 均匀每一个增长:" + ((len1 -len2)/num).toString());
}
    

转载注明盛世游戏:http://www.shengshiyouxi.com


   前一部分测试是创建一批空对象,不作任何其他的操作,那么这些对象的引用计数应该是0
后面一部分测试是创建一批空对象,并将创建的每个对象随后添加到了显示列表,那么这批对象就同时有了引用计数,也即不对这些对象进行其他处理情况下的内存占用。但对Bitmap对象还是略有不同,因为并有为其new 一个bitmapData对象实例,所以bitmap所占内存这里输出的要比实际的低

下面来看测试输出:
  [color=ize:13px]//------------------------------------------------------------------------------->
  每次创建1000个同类对象,测试前总内存大小为:3158016
new Sprite后总内存大小为:3665920
new Sprite后增加的内存为:507904 || 平均每个增加:507.904

new Bitmap后总内存大小为:3788800
new Bitmap后增加的内存为:122880 || 平均每个增加:122.88

new Shape后总内存大小为:4141056
new Shape后增加的内存为:352256 || 平均每个增加:352.256

================以下为创建并添加到显示列表================
new Sprite后总内存大小为:3760128
new Sprite后增加的内存为:-380928 || 平均每个增加:-380.928

new Bitmap后总内存大小为:4505600
new Bitmap后增加的内存为:745472 || 平均每个增加:745.472

new Shape后总内存大小为:4886528
new Shape后增加的内存为:380928 || 平均每个增加:380.928
  [color=ize:13px]//-------------------------------------------------------------------------------->
  可以看到输出中的这段:
  [color=ize:13px]//------------------------------------------------------------->
  new Sprite后总内存大小为:3760128
new Sprite后增加的内存为:-380928
  [color=ize:13px]//------------------------------------------------------------->
  内存增加是负值,如果看作是之前new 出的一批对象实例被回收了,重新创建一批Sprite实例,并添加到显示列表中,比之前仅创建Sprite而不添加到显示列表的内存“new Sprite后总内存大小为:3665920”相比来说,还算是比较合理的。

所以这个负值也就不意外了。
另外,从这个测试函数内的源码注释部分,可以看到“arr.push(sprite);”这样几行,是当时测试new 出来的这一批对象,不添加到显示列表,仅仅增加引用计数而进行的测试,可以与添加到显示列表的内存开销进行一下对比。
  [color=ize:13px]//-------------------------------------------------------------------------------->
  每次创建1000个同类对象,测试前总内存大小为:3158016
new Sprite后总内存大小为:3670016
new Sprite后增加的内存为:512000 || 平均每个增加:512

new Bitmap后总内存大小为:4444160
new Bitmap后增加的内存为:774144 || 平均每个增加:774.144

new Shape后总内存大小为:4796416
new Shape后增加的内存为:352256 || 平均每个增加:352.256

================以下为创建并添加到显示列表================
new Sprite后总内存大小为:5373952
new Sprite后增加的内存为:577536 || 平均每个增加:577.536

new Bitmap后总内存大小为:6160384
new Bitmap后增加的内存为:786432 || 平均每个增加:786.432

new Shape后总内存大小为:6500352
new Shape后增加的内存为:339968 || 平均每个增加:339.968
  [color=ize:13px]//---------------------------------------------------------------------------------->
  看两段输出,很清楚,可以对比着看,不解释。

  三、对图片加载和位图常用操作的对比测试

先看测试函数,这个函数写的还早,测试的还早,所以对输出文字的处理跟前面两个有点不一样。private function compareBitmap():void
{
        var loader:Loader = new Loader();
        var path:String = "1.png";
        
        var url:URLRequest = new URLRequest(path);
        loader.contentLoaderInfo.addEventListener(Event.COMPLETE, imageLoader_Complete);
        len2 = System.totalMemory;
        _txt.text = "载入图片前总内存大小为:" + len2.toString();
        loader.load(url);
}

private function imageLoader_Complete(e:Event):void
{
        var text:String;
        len1 = System.totalMemory;
        text = _txt.text + "\n载入图片后总内存大小为:" + len1.toString();
        
        text += "\n载入后增加的内存大小为:" + (len1 - len2).toString();
        
        var loader:Loader = e.target.loader as Loader;
        var bmp:Bitmap = loader.content as Bitmap;
        text += "\n\nloader的总字节数为:" + loader.contentLoaderInfo.bytesTotal.toString();
        text += "\nBitmap的总字节数为:" + bmp.loaderInfo.bytesTotal.toString();
        
        text += "\n当前总内存大小为:" + System.totalMemory.toString();
        
        var bmpData:BitmapData = bmp.bitmapData;
        len2 = System.totalMemory;
        text += "\n\nBitmapData赋值后的总内存大小为:" + len2.toString();
        bmpData.copyPixels(bmp.bitmapData, new Rectangle(0,0,bmp.width,bmp.height), new Point(0, 0));
        len1 = System.totalMemory;
        text += "\ncopyPixels位图对象的bitmapData后的总内存大小为:" + len1.toString();
        bmpData.draw(bmp);
        len2 = System.totalMemory;
        text += "\nbitmapData.draw()位图对象后的总内存大小为:" + len2.toString();
        var bmp1:Bitmap = new Bitmap();
        text += "\nnew一个Bitmap空对象bmp1后的总内存大小为:" + System.totalMemory.toString();
        bmp1.bitmapData = bmpData;
        text += "\n对bmp1.bitmapData赋值后的总内存大小为:" + System.totalMemory.toString();
        var bmp2:Bitmap = new Bitmap(bmpData);
        text += "\n使用得到的bmpData对象生成bmp2后的总内存大小为:" + System.totalMemory.toString();
        this.addChild(bmp1);
        text += "\n将bmp1添加到显示列表后的总内存大小为:" + System.totalMemory.toString();
        this.addChild(bmp2);
        text += "\n将bmp2添加到显示列表后的总内存大小为:" + System.totalMemory.toString();
        
        bmp1.x = 300;
        bmp1.y = 0;
        bmp2.x = 400;
        bmp2.y = bmp2.height + 10;
        
        text += "\n\n图片宽度=" + bmp.width.toString() + ",高度=" + bmp.height.toString();
        text += "\n按PNG图片像素内存占用<ARGB*width*height>\n来计算,则纯像素占内存= 4 * " + bmp.width.toString() + " * " + bmp.height.toString() + " =" + (4 * bmp.width * bmp.height).toString();;
        
        len2 = System.totalMemory;
        text += "\n\n当前总内存大小为:" + len2;
        bmpData = bmp.bitmapData.clone();
        len1 = System.totalMemory;
        text += "\n克隆位图对象的bitmapData后的总内存大小为:" + len1.toString();
        text += "\n克隆后增加的内存大小为:" + (len1 - len2).toString();
        
        var num:uint = 1000;
        var j:uint;
        var tempBMP:Bitmap;
        var rect:Rectangle = new Rectangle(0, 0, bmp.width, bmp.height);
        var vertex:Point = new Point(0, 0);
        var dt:int = getTimer();
        len2 = System.totalMemory;
        text += "\n\nnum=" + num.toString() + " || 当前总内存大小为:" + len2;                        
        for (j = 0; j < num; j++)
        {
                tempBMP = new Bitmap();
                //tempBMP.bitmapData = bmp.bitmapData;
                tempBMP.bitmapData = new BitmapData(bmp.width, bmp.height);
                tempBMP.bitmapData.copyPixels(bmp.bitmapData, rect, vertex);
               
                this.addChild(tempBMP);
                tempBMP.x = j + 300;
                tempBMP.y = j;
        }
        len1 = System.totalMemory;
        dt = getTimer() - dt;
        text += "\n生成num个位图并添加到显示列表中后的总内存大小为:" + len1.toString();
        text += "\n生成num个位图并添加到显示列表中后增加的内存大小为:" + (len1 - len2).toString();
        text += "\n花费时间:" + dt.toString() + "毫秒 || 平均操作每个对象需时:" + (dt / num).toString();
        _txt.text = text;
}
   转载注明盛世游戏:http://www.shengshiyouxi.com
对上面这段代码里面的for循环里面部分,以循环1000次为例,我进行三种测试。for (j = 0; j < num; j++)
{
        tempBMP = new Bitmap(bmp.bitmapData);
        
        this.addChild(tempBMP);
        tempBMP.x = j + 300;
        tempBMP.y = j;
}
  
上面这种测试由载入的bitmapData直接生成要使用的位图,以方便添加到显示列表中使用。

上面这种测试输出是:
  [color=ize:13px]//------------------------------------------------------------------------->
  载入图片前总内存大小为:3174400
载入图片后总内存大小为:3526656
载入后增加的内存大小为:352256

loader的总字节数为:61831
Bitmap的总字节数为:61831
当前总内存大小为:3526656

BitmapData赋值后的总内存大小为:3526656
copyPixels位图对象的bitmapData后的总内存大小为:3526656bitmapData.draw()位图对象后的总内存大小为:3526656
new一个Bitmap空对象bmp1后的总内存大小为:3526656
对bmp1.bitmapData赋值后的总内存大小为:3526656
使用得到的bmpData对象生成bmp2后的总内存大小为:3526656
将bmp1添加到显示列表后的总内存大小为:3526656
将bmp2添加到显示列表后的总内存大小为:3526656

图片宽度=256,高度=255
按PNG图片像素内存占用<ARGB*width*height>
来计算,则纯像素占内存= 4 * 256 * 255 =261120

当前总内存大小为:3526656
克隆位图对象的bitmapData后的总内存大小为:3788800
克隆后增加的内存大小为:262144

num=1000 || 当前总内存大小为:3788800
生成num个位图并添加到显示列表中后的总内存大小为:4452352
生成num个位图并添加到显示列表中后增加的内存大小为:663552
花费时间:103毫秒 || 平均操作每个对象需时:0.103
  [color=ize:13px]//----------------------------------------------------------------------------->

  再来看将for中代码修改为new出一个空bitmap之后,对其bitmapData赋值的做法,有没有不同。for (j = 0; j < num; j++)
{
        tempBMP = new Bitmap();
        tempBMP.bitmapData = bmp.bitmapData;
        
        this.addChild(tempBMP);
        tempBMP.x = j + 300;
        tempBMP.y = j;
}
   
  请看输出:
  [color=ize:13px]//-------------------------------------------------------------------------------->
  载入图片前总内存大小为:3174400
载入图片后总内存大小为:3526656
载入后增加的内存大小为:352256

loader的总字节数为:61831
Bitmap的总字节数为:61831
当前总内存大小为:3526656

BitmapData赋值后的总内存大小为:3526656
copyPixels位图对象的bitmapData后的总内存大小为:3526656
bitmapData.draw()位图对象后的总内存大小为:3526656
new一个Bitmap空对象bmp1后的总内存大小为:3526656
对bmp1.bitmapData赋值后的总内存大小为:3526656
使用得到的bmpData对象生成bmp2后的总内存大小为:3526656
将bmp1添加到显示列表后的总内存大小为:3526656
将bmp2添加到显示列表后的总内存大小为:3526656

图片宽度=256,高度=255
按PNG图片像素内存占用<ARGB*width*height>
来计算,则纯像素占内存= 4 * 256 * 255 =261120

当前总内存大小为:3526656
克隆位图对象的bitmapData后的总内存大小为:3788800
克隆后增加的内存大小为:262144

num=1000 || 当前总内存大小为:3788800
生成num个位图并添加到显示列表中后的总内存大小为:4456448
生成num个位图并添加到显示列表中后增加的内存大小为:667648
花费时间:17毫秒 || 平均操作每个对象需时:0.017
  [color=ize:13px]//------------------------------------------------------------------------------->
  我之前试了很多次,这种处理,会比上面一种生成时直接以bitmapData来生成bitmap花费的时间要长一点,内存也多一点,不知这次如何,我修改代码后运行直接把输出复制过来了,也没细看。
提交以后看到前一次的输出,时间好久,喜欢动手的下载下面的RAR文件自己多测试几次吧,有时候测试效果不稳定,这很无奈。

下面来看另一种情况,new 出来bitmap后再new 出来一个bitmapData不填充值的对象,然后再利用其CopyPixels函数来处理,在看代码和效果前,一定明白这样相当于这个bitmap采用了一张新的位图,而CopyPixels函数,只是把另外一张位图中的数据重新指向过来。看完修改的代码和输出后,下面再细说。for (j = 0; j < num; j++)
{
        tempBMP = new Bitmap();
        tempBMP.bitmapData = new BitmapData(bmp.width, bmp.height);
        tempBMP.bitmapData.copyPixels(bmp.bitmapData, rect, vertex);
        
        this.addChild(tempBMP);
        tempBMP.x = j + 300;
        tempBMP.y = j;
}
   
  请看输出:
  [color=ize:13px]//------------------------------------------------------------------------------------>
  载入图片前总内存大小为:3174400
载入图片后总内存大小为:3530752
载入后增加的内存大小为:356352

loader的总字节数为:61831
Bitmap的总字节数为:61831
当前总内存大小为:3530752

BitmapData赋值后的总内存大小为:3530752
copyPixels位图对象的bitmapData后的总内存大小为:3530752
bitmapData.draw()位图对象后的总内存大小为:3530752
new一个Bitmap空对象bmp1后的总内存大小为:3530752
对bmp1.bitmapData赋值后的总内存大小为:3530752
使用得到的bmpData对象生成bmp2后的总内存大小为:3530752
将bmp1添加到显示列表后的总内存大小为:3530752
将bmp2添加到显示列表后的总内存大小为:3530752

图片宽度=256,高度=255
按PNG图片像素内存占用<ARGB*width*height>
来计算,则纯像素占内存= 4 * 256 * 255 =261120

当前总内存大小为:3530752
克隆位图对象的bitmapData后的总内存大小为:3792896
克隆后增加的内存大小为:262144

num=1000 || 当前总内存大小为:3792896
生成num个位图并添加到显示列表中后的总内存大小为:266907648
生成num个位图并添加到显示列表中后增加的内存大小为:263114752
花费时间:1236毫秒 || 平均操作每个对象需时:1.236
  [color=ize:13px]//------------------------------------------------------------------------------------>
  看看上面输出结果的最后两行,是不是很让人惊奇,好大的内存增加,以及好长的时间花费,CPU占用还好,我第一次测试时,num=10000,最后超过默认的15秒不响应限制,也没有出来结果,但CPU占用一直稳定在25%(仅FP,还是在debug模式下),而且操作系统提示虚拟内存不足。

从最后一个测试可以看出,我们要尽量少用new BitmapData()这个函数,如果使用了这个函数,基本相当于引入了一张新位图图片。

[color=ize:16px]四、结论和我的猜测
结论将是由以上测试总结出的可验证的判断,但我的猜测就不行了,将仅仅是这些结论往前回溯性的猜测,所以可能被我蒙中了,也可能根本就是瞎猜,看到的各位,可以算做抛砖引玉,由此讨论,但不要就此抬扛。

  1、通过前面对CopyPixels函数的测试,可以看到,这个函数是极节省内存的。与直接使用一个位图的bitmapData数据生成一个新的bitmap基本没有差别。而且速度也很不错。
//--------------------------------------------------------------->
  num=1000 || 当前总内存大小为:3788800
生成num个位图并添加到显示列表中后的总内存大小为:4452352
生成num个位图并添加到显示列表中后增加的内存大小为:663552
花费时间:103毫秒 || 平均操作每个对象需时:0.103
  [color=ize:16px]//--------------------------------------------------------------->
  这段输出是对循环1000次,先给bitmapData赋值,再调用CopyPixels的测试输出,看内存的增加与,跟去掉CopyPixels操作之后基本没有差别。
  
  2、在使用位图资源时,尽可能的少用new BitmapData来生成位图,因为这相当于载入了一张新位图。

  3、位图资源无论文件本身如何压缩,如何小,但载入内存后,其占用的内存空间,基本可按<ARGB*width*height>来计算,当然实际结果会比这个数值略大,这可以从测试中的Clon()函数的调用内存增加看出。

4、由结论3,可以推导出一个游戏的flash客户端中,究竟可以引入多少位图资源,按照webgame的内存占用率一半,CPU等计算资源30%的原则来算占用的最大内存,单独一个web game的内存占用量上限可考虑300MB~600MB,以轻量级的web game 上限内存300MB来算,那就是1024*1024分辩率的图片JPG之类无alpha通道的图片100张,PNG格式有alpha通道的图片75张,无论是矢量存储载入后转位图,还是直接就是位图。而这个位图资源的上限公式,可以作为一个游戏项目的主策划用来限制随意策划的一个测量标尺。

  //---------------------------------------------------------------------------------------------------------------------->
  以下是我猜测性的推论,请审慎视之
1、从内存增量上来看,使用已载入的位图资源数据来new 出一个新的位图,应该仅是生成了一个位图对象,而实际的位图数据还是指向原始的位图资源。

2、人为的在代码中调用垃圾回收机制,既没必要,也不需要,反而徒增系统资源的浪费。

3、普通对象的引用计数清除很重要,这关系到这些对象占用内存的回收。

4、位图类对象的位图数据,调用销毁函数很有必要,在不使用某个位图资源时,将某个位图资源手动销毁,垃圾回收并不起作用。

5、bitmapData相比普通的类对象,要特别一点,特别之处有二,一是该对象引用指向的对象实际数据区,需要手动销毁才能退出占用的内存;另一是对该对象引用指向的实际数据,在进行数据修改,以让其显示的位图有不同的显示效果时,该修改并不是直接在实际的原始数据上进行修改的。

6、从bitmapData的特别之处,可以看到,流布于一些AS3效率优化文章内的慎用滤镜等之类的看法,应该也是这个问题的延伸。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Open3D是一个用于3D数据处理的开源库,其包含了许多常用的点云可视化方法。下面让我们一起来了解一些常用的点云可视化方法。 要可视化点云,首先需要将点云读入Open3D。可以使用`o3d.io.read_point_cloud`函数从文件读取点云,也可以使用`o3d.geometry.PointCloud`类手动创建点云。例如,可以使用以下代码创建一个包含随机点的点云: ```python import open3d as o3d import numpy as np # 生成一个包含100个随机点的点云 points = np.random.rand(100, 3) # 100个点,每个点有3个坐标 pcd = o3d.geometry.PointCloud() pcd.points = o3d.utility.Vector3dVector(points) ``` 接下来,可以使用以下方法将点云可视化: 1. 使用`o3d.visualization.draw_geometries`方法可视化单个点云。 ```python import open3d as o3d import numpy as np # 生成一个包含100个随机点的点云 points = np.random.rand(100, 3) # 100个点,每个点有3个坐标 pcd = o3d.geometry.PointCloud() pcd.points = o3d.utility.Vector3dVector(points) # 可视化点云 o3d.visualization.draw_geometries([pcd]) ``` 2. 使用`o3d.visualization.Visualizer`类可视化多个点云。 ```python import open3d as o3d import numpy as np # 生成两个包含随机点的点云 points1 = np.random.rand(100, 3) # 100个点,每个点有3个坐标 pcd1 = o3d.geometry.PointCloud() pcd1.points = o3d.utility.Vector3dVector(points1) points2 = np.random.rand(50, 3) # 50个点,每个点有3个坐标 pcd2 = o3d.geometry.PointCloud() pcd2.points = o3d.utility.Vector3dVector(points2) # 创建可视化器 vis = o3d.visualization.Visualizer() vis.create_window() # 将点云添加到可视化器 vis.add_geometry(pcd1) vis.add_geometry(pcd2) # 显示场景 vis.run() # 关闭窗口 vis.destroy_window() ``` 3. 使用`o3d.visualization.draw_geometries_with_key_callbacks`方法添加交互式控件。 ```python import open3d as o3d import numpy as np # 生成一个包含100个随机点的点云 points = np.random.rand(100, 3) # 100个点,每个点有3个坐标 pcd = o3d.geometry.PointCloud() pcd.points = o3d.utility.Vector3dVector(points) # 可视化点云,并添加交互式控件 def rotate_view(vis): ctr = vis.get_view_control() ctr.rotate(10.0, 0.0) o3d.visualization.draw_geometries_with_key_callbacks([pcd], {'r': rotate_view}) ``` 在这个示例,我们使用`o3d.visualization.draw_geometries_with_key_callbacks`方法可视化一个点云,并添加了一个交互式控件,按下'r'键可以旋转视角。 除了上述方法外,Open3D还提供了许多其他的点云可视化方法,如使用不同的颜色和大小可视化点云、可视化点云的法向量、可视化点云的曲率等等。可以参考Open3D的官方文档了解更多信息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值