在游戏压测的时候,内存泄漏往往是导致游戏挂掉的最最重要原因。
而导致泄漏最大的嫌疑元凶,就是游戏中大量的缓动。也就是本文的主角TweenLite与TweenMax。
常见的写法:
var tween:TweenLite = TweenLite.to(ball, 1, {x:mouseX, y:mouseY });
另外一种,网上流传说能避免泄漏的写法:
var tween:TweenLite = TweenLite.to(ball, 1,{x:mouseX, y:mouseY, onComplete: function(){ tween.kill() } });
事实的真相却是,这两种写法都无法避免TweenLite对象的泄漏。
经过仔细排查,内存泄漏其实跟你kill() 或者不kill()没有什么直接的关系。甚至调用TweenLite.killTweensOf()都是无法从根源上解决泄漏的问题。
只要时间一到,tween实例就会从TweenLite 的时间轴(TimeLineLite)上被移除。kill()的作用只不过是提前终止缓动而已。
问题的关键在于,即使tween实例从时间轴上被移除,也不代表它就能够被Garbage Collection给回收掉。
从下面的代码截图,可以很容易看出,真正导致tween对象未能被回收真正原因,竟然是,当tween实例被从时间轴上remove下来的时候,它只修改链条的上一个节点和链条的下一个节点的preNode和nextNode。并没有把自身节点的preNode和nextNode的引用给删除。试想,如果这个“链条”一直不间断的增长,比如每帧里面都在执行TweenLite.to()。这就意味着它永远无法释放,并且越来越长。简直太可怕了。
解决办法就是这样:
TweenLite.killTweensOf(tween.target,false,null); tween.prevNode = null; tween.nextNode = null; tween.target = null; tween.vars = null; tween.data = null; tween = null;