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); } }
  • 相关阅读:
    hadoop用到的shell脚本
    hadoop搭建完全分布式集群
    hadoop搭建伪分布式集群
    ARM Compute Library编译安装
    OpenBlas交叉编译安装
    正则表达式去除所有标签html标签
    xstream实现xml字符串与对象直接的转换
    spring-boot中使用mybatis-plus代码生成器让你轻松的完成单表的CURD
    开源、免费软件和网站分享
    2020春软件工程助教工作期末总结
  • 原文地址:https://www.cnblogs.com/axyz/p/2100363.html
Copyright © 2011-2022 走看看