AS3大型游戏性能随着时间的推移而降级

时间:2009-09-21 21:15:01

标签: flex actionscript-3 performance memory-leaks

我目前正在制作一个非常大的Flash平台游戏(数百个课程)并处理一个问题,如果你让游戏停留足够长时间,游戏会慢慢停止。我没有写游戏,所以我只是模糊地熟悉它的内部。一些神秘的症状包括,

  • 游戏将在确定的时间内(在给定的级别上)正常运行,突然间会以指数方式开始泄漏内存。
  • 当屏幕上有更多精灵时,游戏达到指数级泄漏所需的时间会缩短。
  • 即使没有任何东西可以在屏幕上显示,游戏也会慢下来。
  • 游戏中更频繁的精灵碰撞会使游戏速度变慢。
  • 完全禁用冲突代码确实可以减慢降级速度,但不会阻止游戏最终丢帧。

查看源代码并使用Flex分析器,我的主要嫌疑人是,

  • 有许多游荡物品,尤其是WeakMethodClosure,会占用大量内存。
  • 该程序非常广泛地使用弱事件侦听器(每帧调度数十个)。
  • 每次创建新的精灵时都会复制BitmapData。这些是50x50像素的精灵,每秒产生约8个精灵。

我知道在没有看到来源的情况下几乎不可能告诉我这个问题,所以我只是在寻找可以帮助我缩小范围的花絮。有没有人在他们自己的项目中经历过这种规避性能下降?你案件的原因是什么?

7 个答案:

答案 0 :(得分:7)

我最近完成了一个大型项目的优化。 我可以给你一些建筑建议:

  1. 主要原则 - 尝试尽可能少地执行功能/事件调用
  2. 摆脱除一个之外的所有人 onEnterFrame / onInterval / onTimer周期。尽你所能 需要在一个一般事件调用中。 您可能需要大量静态数组来存储已处理的对象 引用。
  3. 您的图形/渲染内容也在一个主循环
  4. 尝试使用大(可能是预呈现的)画布而不是小精灵/位图。 通常它可用于背景。但也适用于较小的物体 (如树木,平台等)
  5. 摆脱小位图资源,将其组合到一个图块并绘制您的东西 直接来自它,通过source-rect属性
  6. 我希望它对你有所帮助! 内存泄漏 - 如此头痛。

    P.S。在不同的浏览器中测试你的游戏,IE - 大多数都是泄漏,有时它每次刷新后都不会清除内存。

答案 1 :(得分:3)

  • 避免使用匿名方法 - 将它们更改为类级方法。
  • 在addEventListener中使用弱引用和/或确保在删除对象的所有侦听器之前使用removeChild删除它
  • 确保你删除所有精灵,而不是让它们飞离屏幕。此外,如果可能,重用精灵而不是创建新精灵。

答案 2 :(得分:1)

如果你有很多创建/破坏,你应该考虑对象池,特别是对于像bitmapdata这样的重量对象。

请参阅Object Pool class

答案 3 :(得分:0)

听起来您需要对应用程序进行分析,以了解正在发生的事情。

这个帖子有一些建议,但是,最终,你需要输入代码来帮助确定发生了什么。

Profiling ActionScript-3 Code

您可能想知道是否可以在一段时间内运行一些较小的部件,看看是否看到减速。

您可能希望对应用程序进行单元测试,以便快速运行各个部分,查找内存泄漏。 一个框架是:http://asunit.org/,另一个框架是:http://opensource.adobe.com/wiki/display/flexunit/

单元测试是我使用大量的分析,所以你可以在游戏的顶层测试,运行数千次,寻找问题,然后运行每个部分,看看哪些有问题,然后工作你的方式下来。这是一个手动过程,但如果开头列出的SO线程中的两个想法没有帮助,这可能是您最好的方法。

你是否使用了太多内存?或者您的CPU使用率是否过高?

答案 4 :(得分:0)

首先确定您的内存或处理器限制是否正在击中。这听起来像是后来的,似乎有许多物体在做什么......可能那些额外的精灵没有得到很好的释放。在这些事件中查找对象/变量/任何事物之间的依赖关系,确保删除了精灵,注意任何EnterFrame处理程序或重复事件。

答案 5 :(得分:0)

听起来你更有可能限制处理器速度而不是内存。你必须为Flash应用程序尝试额外的内存功能。

幸运的是,你可以采取很多简单的方法来降低CPU的压力......

1)严格管理所有的事件监听器,特别是鼠标监听器。你的所有精灵对象上都有$ texas事件监听器吗?这可能是个问题。

2)使用int或uint而不是Number访问数组。这是巨大的,这是其中一个回归的Adobe技巧。使用int和uint访问数组对象比使用Number更快,如果你进行了大量的迭代(听起来就像你这样做),这可能会使你的帧执行时间缩短几毫秒。

3)与#2一样,监视您的数学运算以及您用于某些操作的类型。在AS3的数学运算中,你可以做的最慢的事情是重复投射(向返回数字的函数提供内联),或执行基本操作,如在Number而不是int上添加和减去。

在Flash中使用这样的wtfhuge程序的好处是,即使是微小的优化更改也会对性能产生重大影响。我曾经在AS3中玩过一个光线跟踪引擎,在那里我宣布了一个额外的变量,它将我的FPS从30秒杀死到23个。

答案 6 :(得分:0)

Flash有一个相当臭名昭着的问题(许多人认为它是一个错误)导致事件监听器的计时器和ENTER_FRAME事件不被垃圾收集,即使它们被弱引用。因此,尽管使用弱引用事件是一种很好的做法,但仍然应该在不再需要时删除所有事件侦听器。