zoukankan      html  css  js  c++  java
  • timer

    编辑器加载中...Timer 1. 官方说法   无限次Timer可能会引起内存泄露,有限次Timer不会引起内存泄露 2. 实际情况(见测试用例)   a)无限次Timer     i.Timer在运行中且注册了TimerEvent.Timer事件侦听器,则侦听器对象本身不会被回收     ii.Timer没有调用start()或者start后调用了stop(),侦听器对象会被垃圾回收     iii.Timer调用了start(),但是没有对Timer注册事件侦听器或者事件侦听器被移除,不存在对侦听器垃圾回收问题   b)有限次Timer     i.Timer在运行中且对Timer注册了事件侦听器,则侦听器对象不会被回收     ii.Timer调用了stop(),侦听器对象会被回收     iii.Timer在运行了指定的repeat次数后,侦听器对象会被回收 3.结论   Timer在运行中且注册了事件侦听器(一般用Timer,肯定会注册事件侦听器),侦听器对象不会被回收;   由于有限次Timer迟早有结束的那一刻,所以有限次Timer一般不会造成内存泄露,但是可能会造成侦听器对象延迟释放;   而无限次Timer则可能引起内存泄露,在一个对象释放后,如果对象内部的Timer没有停止或者没有移除事件侦听器,则对象永远不会被释放 4.好的习惯   a)能用有限次Timer的情况,不要用无限次Timer   b)无论是有限次Timer还是无限次Timer,在不再需要Timer时显式地调用Timer.stop(),或者移动事件侦听器(removeEventListener),并且建议两项工作都做。 5.测试用例及说明   测试一中,在文档类中创建了一个TestTimer(test),注意这是一个局部变量。在TestTimer构造函数中,创建了一个每100毫秒触发一次的无限次Timer,并添加相应的侦听器,最后调用Timer.start()启动Timer,这时虽然程序中没有任何对TestTimer的引用,运行GC可以发现TestTimer对象不会被销毁;   在测试二中,与测试一唯一不同的地方在于没有对timer添加事件侦听器,即少了timer.addEventListener(TimerEvent.TIMER, handleTimer),在profile中运行gc,发现testTimer的实例由1变为0,说明这种情况不会造成内存泄露;   在测试三中,与测试二的不同在于,添加了事件侦听器,但是没有调用timer.start(),这时发现结果与测试二相同;针对测试三,可以测试另一种情况,在构造函数中调用timer.start(),但是在handleTimer中调用timer.stop()或者removeEventListner(TimerEvent.TIMER, handleTimer),测试结果与测试二相同;   在测试四中,指定了一个执行200次的Timer(new Timer(100,200)),在Timer执行结束前,无法回收TestTimer实例,在执行完毕后可以正常回收,说明侦听器是否能被gc,是完全依赖于Timer是否在运行中,对于无限次Timer,如果不调用stop(),侦听器则不能被回收; public function Test(){ var test:TestTimer = new TestTimer(); } } public class TestTimer { private var timer:Timer; public function TestTimer() { timer = new Timer(100); timer.addEventListener(TimerEvent.TIMER, handleTimer); timer.start(); } private function handleTimer (event:TimerEvent):void { trace(“timer”); } } setInterval      如果不调用clearInterval,setInterval调用的函数所在对象永远不会被回收,这是显而易见的,有怀疑精神的童鞋可以自己去做测试,就不写测试代码了;如果怀疑这个的话,建议也去测试一下,as中(1+1)==2是不是返回true,o(^_^)o~~~哈哈!! setTimeout   1, 如果不调用clearTimeout,setTimeout引用的对象永远不会被回收,无论timeoutHandler是否已经执行,clearTimeout的作用不仅仅是中断未执行的timeoutHandler,更重要的是,如果不调用clearTimeout,声明timeoutHandler的对象不会被gc   2, 测试如下代码,发现gc时,TestTimeOut的实例能够正常释放;   3, 如果在下面的代码块的timeoutHandler中不调用clearTimeout(timeoutId),虽然此时timeoutHandler已经执行过,TestTimeOut对象在gc执行时仍然不会被回收;   4, 关于setTimeout,多说一句, setTimeout其功能相当于只执行一次的Timer,而Timer执行一次后,无论是否stop()或者removeEventListener,其事件侦听对象都可以被正常gc;个人觉得这应该也算是设计上的失败,我一直以为clearTimeout只是用来在timeoutHandler执行之前用来取消setTimeout的;   而且其中文帮助文档是这样说的(如果是翻译出错,算我倒霉):   如果打算使用 clearTimeout() 方法取消 setTimeout() 调用,请确保将 setTimeout() 调用分配给一个变量(clearTimeout() 函数稍后将引用该变量)。如果不通过调用 clearTimeout() 函数取消 setTimeout() 调用,则不会将包含设置的超时 closure 函数的对象作为垃圾回收。   如果只看前半句,我绝对不会想到这个还会影响到gc,小小地钻一下文字牛角尖:如果我不打算取消本次setTimeout()调用,那么是不是也就不必要记住tiemeoutId,那么也就无从调用clearTimeout了;   后半句,个人认为是有歧义的(当然还是可能是翻译出了差错),而且我想了很久,这段话连起来读,第二种理解也符合一些:   理解一:如果不调用clearTimeout,那么包含超时closure函数的对象永远也无法垃圾回收(无论超时回调closure函数是否已经执行),这个和测试结论一致,也是正确的理解;   理解二:如果不调用clearTimeout函数,在设置的超时closure函数在执行前,包含该函数的对象不能作为垃圾回收;   假设设置的超时closure函数所在对象没有其他引用,或者closure只是在主函数内部定义的一个局部函数, setTimeout调用执行前的确是不应该回收的,这样第二种理解也可以自圆其说。 public function Test(){ var test:TestTimeOut = new TestTimeOut (); } } public class TestTimeOut { private var timeoutId:int; public function TestTimeOut () { timeoutId = setTimeout(timeOutHandler); } private function timeOutHandler ():void { clearTimeout(timeoutId); } }
  • 相关阅读:
    Codevs 2296 仪仗队 2008年省队选拔赛山东
    Codevs 1535 封锁阳光大学
    Codevs 1069 关押罪犯 2010年NOIP全国联赛提高组
    Codevs 1218 疫情控制 2012年NOIP全国联赛提高组
    Codevs 1684 垃圾陷阱
    洛谷 P1108 低价购买
    Vijos P1325桐桐的糖果计划
    Codevs 3289 花匠 2013年NOIP全国联赛提高组
    Codevs 2611 观光旅游(floyed最小环)
    C语言基础之彩色版C语言(内含linux)
  • 原文地址:https://www.cnblogs.com/axyz/p/2100363.html
Copyright © 2011-2022 走看看