优化Flash性能(三)

管理内存

下面列的建议不够详尽,但它包括了那些可以大幅度提升Flash性能的策略内容。

使用回调函数 VS dispatEvent

当派发事件的时候会增加内存的使用,因为每个事件必须被创建并且分配内存给它。这种行为是这样解释的:事件也是对象,因此也需要内存。

我试着发送少量事件,发现每个消耗40到128字节。我也发现使用回调函数会使用更少的内存,比使用事件效率更高。(查看在实例文档里的测试文件callback_v_dispatchEvent。)

应用滤镜

当你大量应用滤镜时也很消耗内存。根据Adobe帮助文档,使用一个滤镜会消耗双倍内存。在真实Flash Professional CS6的测试环境中,我曾发现使用滤镜的确会增加内存消耗,但是这种消耗不接近双倍内存。(回顾测试范例,在filters文件夹下)

为每个元素使用正确类型的现实对象

Shape,Sprite,和MovieClip对象每个都使用不同的内存数量。一个Shape对象需要236字节,Sprite需要412字节,MovieClip需要448字节。

如果你在一个工程里使用上千的显示对象,如果不需要交互的话,你也许需要大量Shape类来拯救你的内存。或者,当不需要时间轴时使用Sprite类。

对象池

当你打开你的应用时,要创建各种你会一直使用的对象引用,对象池可以将这些引用保存在数组里。任何时候一个对象需要时,就可以从这个数组里取出使用。

无论何时当一个对象不再需要时,把它再重新放回数组里。

有种常规做法是用Vector来代替Array来存储相同类型的对象。使用Vector也许可以比使用Array快两倍,但是!除非你要做成百上千次的操作,否则你不会注意到两者的差别,因为小于上千次的操作它们一样快。(可以看看array_v_vector 文件夹下的范例文件。)

使用对象池可以获得性能上的好处,同时更主要的收益是让管理内存变得简单。如果你在内存利用方面有无限制增长的问题,用对象池可以很好的解决,它是提高性能、降低内存使用的通用技术。

我看到当测试一个每帧包含许多要垃圾回收和再利用的SWF文件里,使用对象池后帧频快了10%,而内存使用则减少了10%。(可以查看pooling_v_gc 文件夹里的范例。)

重用对象

当你要在一个循环里创建许多对象时,最好在循环外先创建一个对象,然后再循环里重复利用它。当然这个方法也不是对所有工程都有效的,但在很多情况下这个技术还是有用的。

在描述位图传输的单元包括一个重用大量对象的例子。你可以在测试文档里看这是怎么实现的。

处理声音

有关声音的问题在内存使用方面是非常小儿科的。当播放一段声音时,它不可能被垃圾回收的(可以使用Flash Professional CS6来测试文件)。当声音播放完或一个SoundChannel实例执行停止声音时,Sound类就准备垃圾回收了。(想学更多的话可以看看名为sound_test 文件夹下的范例。)

使用Timer

使用Timer时要格外小心。如果没有停止Timer(有两种情况:1.currentCount 属性小于它的循环次数;2.没有调用stop()方法),Timer就不会被垃圾回收,即使你已经移除了侦听器,然后将所有引用设为null。一旦你移除了侦听器,Timer的侦听函数就不被再次调用,但是Timer却仍然消耗内存。

Timer类仅仅使用72字节的内存,所以很可能在一个基于桌面/浏览器的Flash游戏里成为一个很不起眼的问题。但是,当你在移动设备里反复的打开、播放、关闭游戏,然后不断重复启动游戏,你也许就看到这个难以忽略的问题了。

看看这个代码,打开命名为gc_timer_test文件夹下的文件。

弱引用侦听器 VS 强引用侦听器

另一种无法预料的测试结果是,你使用MT类没有办法看出使用弱引用侦听器和强引用侦听器的差别。在Flash Professional CS6环境下我的测试里它们都被当做弱引用侦听器来对待。(查看strong_v_weak_listeners 文件夹下的范例。)



发表评论

电子邮件地址不会被公开。 必填项已用 * 标注

*

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

(Spamcheck Enabled)