BitmapData是内存杀手。

68 views
Skip to first unread message

pawaca

unread,
Oct 23, 2005, 8:18:30 AM10/23/05
to Flash Platform
最近发现BitmapData好像和传统的Image还不太一样,比如:

graphics.beginBitmapFill(bitmapData);
graphics.drawRect(0,0,bitmapData.width.bitmapData.height);
graphics.endFill();
bitmapData.dispose();

这段代码调用后实际上屏幕上什么都没有,而不是像感觉的那样会画出
bitmapData 的内容。也就是说 graphics.beginBitmapFill
并不是画完就完了,还和被传入的 bitmapData
参数建立了某种联系。以至于我们在 endFill
调用之后再修改 bitmapData 屏幕上的显示也会跟着变。

从另一个角度说下面的代码是危险的:

function drawingOp():Void
{
var tmpData:BitmapData=new BitmapData(width,height,true,0x00ffffff);
graphics.beginBitmapFill(tmpData);
graphics.drawRect(0,0,tmpData.width.tmpData.height);
graphics.endFill();
}

即使之后 graphics 再去 fill 别的 BitmapData,例子中的
tmpData 的内存也是不会被释放的!

我写了个例子到 CVS,名字叫
BitmapDataTest,大家可以看看内存是如何尴尬的消失的。。。。

这不知道算是个bug,还是个特性,反正我个人不太喜欢:(

iiley

unread,
Oct 23, 2005, 9:32:01 AM10/23/05
to flashp...@googlegroups.com
我想这应该是一个特性,创建一个BitmapData就像创建一个MC一样,不手动remove它,它是不会消失的。这样可能跟BitmapData文档中的这段说明有关:This
class lets you separate bitmap rendering operations from the Flash
Player internal display updating routines.

他们是分离的,所以draw一次就永远在那里(除非你调用clear),然后实际上每帧更新的时候,FlashPlayer就把BitmapData中的数据根据graphics与它的联系绘制到屏幕上,这样有个好处就是,当改变内容的时候,你不用再次调用beginBitmapFill,然后draw。只需要更改BitmapData中的数据,就可以实现屏幕的变化。(只是推断,需要实践证明)

当然你提到的那种drawingOp的用法,就不行了。可能就需要把tmpData放在外面,在每次重画的时候clear.

这样的特性,能够替flash简化内存管理,但是对于用户,可能感觉有些别扭。


在 05-10-23,pawaca<paw...@gmail.com> 写道:


--
iiley
AsWing http://www.aswing.org
Blog http://spaces.msn.com/members/iiley/

pawaca

unread,
Oct 23, 2005, 9:46:15 AM10/23/05
to flashp...@googlegroups.com
对,稍一不留神内存就没了。我发现这个问题时在想实现一个 drawText 的工具方法时遇到的。我是想达到这样一个目的:每次调用
drawString(graphics,"someText",someStyle),就可以把对应风格的文字画到 graphics
上,这样节省不经常改变的 TextField 的开销,不过最后发现每回都要生成一个临时的 BitmapData 来表现文字,而这个临时的
BitmapData 却不能自动释放,最好导致这个方法没法实现,挺尴尬的。
一个解决办法是保存文字所表现的 BitmapData 的引用,然后在invalidate的时候 dispose 一下,再在 validate
的时候重新生成。 好麻烦 -__-


--
The browser is not a television.

Arri...@gmail.com

unread,
Oct 23, 2005, 11:13:01 AM10/23/05
to Flash Platform
嗯,Flash一向都是自动管理内存的,即使delete也和C++的delete不同,仅仅是set
null而已。Macromedia这次破例给了个dispose,就是考虑到BitmapData的这个feature。呵呵,和以往的风格很不同。感觉BitmapData就是FlashPlayer里面的非托管资源。有一个很有趣的现象:
import flash.display.BitmapData;
var bitmapData:BitmapData = new BitmapData(100, 100, false,
0xFFFF0000);
var graphics:MovieClip = this.createEmptyMovieClip("graphics",
this.getNextHighestDepth());
graphics.attachBitmap(bitmapData, 2);
trace(graphics.getInstanceAtDepth(2));
trace(typeof graphics.getInstanceAtDepth(2));
trace(graphics == graphics.getInstanceAtDepth(2));
---------------------------------------
_level0.graphics
movieclip
true
居然得到的是自己?!
用attachBitmap加到MC里的东西就从此不可访问了,而销毁唯一办法就是dispose。我想如果一个mc的一个depth上已经attach了一个BitmapData对象,再在同一个depth上attach另一个BitmapData会怎样呢?原来的应该被替换掉。
这段代码就不可避免地要造成内存leak
var graphics:MovieClip = this.createEmptyMovieClip("graphics",
this.getNextHighestDepth());
graphics.attachBitmap(new BitmapData(100, 100, false, 0xFFFF0000), 2);
要小心啊~

pawaca

unread,
Oct 23, 2005, 11:23:32 AM10/23/05
to flashp...@googlegroups.com
graphics == graphics.getInstanceAtDepth(2)

这个强! 看来 as3 的 api 在对待 BitmapData 和 Bitmap 上还是比较含糊。(Flash 8得更像是在应付差事-__-)

Arri...@gmail.com

unread,
Oct 23, 2005, 11:31:18 AM10/23/05
to Flash Platform
sorry,我在上面写的是AS2,flash8,不是AS3,真不好意思,下次一定注明!

pawaca

unread,
Oct 23, 2005, 11:34:36 AM10/23/05
to flashp...@googlegroups.com
汗,我说的不是你,是MM在写Flash 8 的 api时像是在应付差事-__-|||

这里欢迎任何有意思的讨论,不管是as几 :P

On 10/23/05, Arri...@gmail.com <Arri...@gmail.com> wrote:

> sorry,我在上面写的是AS2,flash8,不是AS3,真不好意思,下次一定注明!
>

pawaca

unread,
Oct 23, 2005, 10:18:11 PM10/23/05
to Flash Platform
刚才我发现 flash.system.System 里有个叫 totalMemory
的属性。于是把BitmapDataTest稍微修改了一下,
然后我发现即使 dispose 了临时的 BitmapData
内存占用依然在不断上涨(也许我代码别的部分有内存问题,不过我没有发现。),好奇怪,这叫我如何是好-___-
另外,把 dispose
语句注释掉之后,发现内存占用飞速的上涨,不过过了一段时间内存又降回到初始的数值,然后继续飞速上涨,之后就再也没有再次降回来。是不是目前的
alpha 版 Player 在垃圾回收方面还存在问题?

iiley

unread,
Oct 23, 2005, 10:27:02 PM10/23/05
to flashp...@googlegroups.com
垃圾回收的特点。都是在CPU空闲的时候或者内存吃紧的时候才回收的,并不是dispose或者失去引用就立刻被回收了。一般来说你试试把flash
player或者播放那个swf的浏览器最小化,此时应该就会清理内存。

2005/10/24, pawaca <paw...@gmail.com>:

pawaca

unread,
Oct 23, 2005, 10:35:07 PM10/23/05
to flashp...@googlegroups.com
真的耶~~ 谢谢iiley ;)

7yue

unread,
Oct 23, 2005, 10:52:13 PM10/23/05
to flashp...@googlegroups.com
典型的垃圾回收机制,不过效率还是as1,as2的avm的效率。

在 05-10-24,pawaca<paw...@gmail.com> 写道:


--
Zerlot Ma
System Engineer,Great China.
Macromedia,Inc.
Losing faith,will lose everything.
www.7yue.com

Reply all
Reply to author
Forward
0 new messages