【原创】Flash的垃圾回收机制和内存泄露

ActionScript3.0垃圾回收器使用两种方法定位无引用的对象,引用计数法和标识清除法。
  • 引用计数法,一种用于跟踪活动对象的较为简单的方法,它从ActionScript1.0开始使用。当你创建一个指向某个对象的引用,该对象的引用计数器 加1;当你删除该对象的一个引用,该计数器减1。当某对象的计数器变成0,该对象将被标记以便垃圾回收器回收。
    引 用计数法简单,它不会非CPU带来巨大的负担;多数情况下它工作正常。不幸地是,采用引用计数法的垃圾回收器在遇到循环引用时效率不高。
  • 标识清除法,flash player遍历整个对象树,将一切活动对象进行标记,标记过程结束后,没有被标记的就认为可以删除了,当运行GC的时候就把这些对象删除。标识是指强引用。标记-清除法非常准确。但是,由于 Flash Player 遍历你的整个对象结构,该过程对CPU占用太多。Flash Player 9 通过调整迭代标识-清除缩减对CPU的占用。该过程跨越几个阶段不再是一次完成,变成偶尔运行。
内存泄露的原因:
  1. 增加了监听,不需要的时候没有删除;
  2. 没有移除显示列表;
  3. 生成的实例没有销毁;
  4. 。。。

总之,就是存在强引用。

避免方法:

       在不需要用到某个实例的时候,消除与其关联的强引用。比如,移除不再使用的监听器,不再使用的显示对象移除显示列表等。最保险的方法是每个类有自己的GC方法,当不用的时候对应的实例运行一下。

检查方法:

        用flash/flex的IDE,运行profile模式,观察“活动对象”栏目,进行监控,反复的进行一些可疑的操作。如果累计实例和当前实例的数目相等或者很接近,并且内存使用情况的曲线明显上扬,那多半是有内存泄露问题了。profile不是非常的准确,虽然也有强制GC的按钮。使用System.totalMemory进行检测是最准确的方法,但是不能看到各个实例的内存使用情况。

多说几句:

Your objects will not be removed immediately when all active references are deleted.they will be removed at some indeterminate time in the future。

为了避免用户体现到播放器崩溃,可以检测System.totalMemory,出现异常跳转页面,记得保存好当前的游戏信息。

it is not counted in reference counting, and it is not followed for mark sweeping.This means that if the only references remaining to an object are weak, it will be available for collection on the next GC sweep.

officially unsupported,new LocalConnection().connect('foo');测试可以用LocalConnection,抛出异常会执行一次GC,产品里就不要有这些代码了。

stage.window.minimize();
stage.window.restore();通过最小化和恢复窗口,可以比较环保,强制GC,但是要想办法让整个过程不被用户发现。

你可能感兴趣的:(游戏,Flex,活动,Flash,ide)