Upgrade to Pro — share decks privately, control downloads, hide ads and more …

GC算法和IE中JS内存泄露

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
Avatar for xwcoder xwcoder
December 06, 2012

 GC算法和IE中JS内存泄露

09、10年用ExtJS1.1做OPOA时整理的一份关于内存泄露的文档。现整理成PPT。

Avatar for xwcoder

xwcoder

December 06, 2012

Other Decks in Technology

Transcript

  1. 三大传统算法:Reference Counting (引用计数) obj v1 v2 v3 count: 3 循环引用问题

    (从前有座山,山上有座庙,庙里有个老和尚, 老和尚在给小和尚讲故事,讲的啥? 从前有座山,山上有座庙…)
  2. 三大传统算法:Mark-Sweep (标记-清除) Step:1 V1 Q:被使用吗 A: yes, 标记为1 V2 Q:被使用吗

    A: yes, 标记为1 V3 Q:被使用吗 A: no … Q:被使用吗 A: yes Step:2 V1 V2 V3 未被标记,回 收 … 未被标记,回 收
  3. 三大传统算法: Copying (复制) 运行 obj1 obj2 obj3 obj4 using using

    using GC时 obj1 obj2 obj3 obj4 using using using GC后 obj1 obj2 obj3 obj4 using using using
  4. Mark-Compact (标记-整理) step 1: 标记被使用的对象 step 2: 未标记对象和标记对象向相反方向移动 step 3:

    释放未标记对象 • 没有内存浪费 • 效率不错 • 没有内存碎片 结合Mark-Sweep and Copying
  5. Incremental Collecting (增量收集) 基于Mark-Sweep and Copying 实时性较好 M.L.Minsky D.E.Knuth 做了早起研究

    G.L.Steele 1975 Multiprocessing compactifying garbage collection (多进程整理垃圾收集) H.G.Baker 1978 List Processing in Real Time on a Serial Computer (串行计算机上的实时表处理技术) 阐述了多进程环境下的增量收集算法
  6. 那些使用垃圾回收的语言 * 1960 lisp * 1964 Simula * 1969 Smalltalk

    * 1970 Prolog * 1973 ML * 1975 Scheme * 1983 Modula-3 * 1986 Eiffel * 1987 Haskell ...... * java, .net, javascript ......
  7. 浏览器JS引擎GC算法现状 • 截止2008 所有现代浏览器使用Mark-Sweep, even IE • IE <= 8

    BOM and DOM are COM, COM使用引用计数 • IE9 makes BOM and DOM objects into true JS object IE: window.!CollectGarbage() Opera (>=7): window.opera.collect()
  8. 浏览器JS引擎 GC算法现状 • 截止2008 所有现代浏览器使用Mark-Sweep, even IE • IE <=

    8 BOM and DOM are COM, COM使用引用计数 • IE9 makes BOM and DOM objects into true JS object IE: window.!CollectGarbage() Opera (>=7): window.opera.collect()
  9. 何时执行GC IE6 一组阀值: { 256个变量 4096个对象或数组 64K string } 达到其一就执行GC

    IE7 默认阀值 同IE6 GC回收率 < 15%,defalut * 2 GC回收率 > 85%,default还原
  10. ExtJS1.1 中事件造成的泄露问题 Memory Leak is an important thing, especially in

    OPOA especially in OPOA especially in OPOA especially in OPOA
  11. 事件绑定 step 1:Ext.EventManager.on step 2:Ext.lib.Event.on 1. 将fn包装得到h 2. 将h放到fn的属性中 3.

    将h包装得到wrappendFn 4. 将h、wrapFn存储在静态变量 5. 将wrappendFn绑定到el ExtJS1.1 中事件造成的泄露问题
  12. 事件移除 Element.removeListener Element.removeListener( fn ) //原始fn 1. 从fn的_handlers中删除h的引用 2. 对h调用

    Ext.lib.Event.removeListener Ext.lib.Event.removeListener 1. 找到缓存在listeners中的数据 2. 从listeners将缓存删除 ExtJS1.1 中事件造成的泄露问题
  13. 事件移除 Element.removeListener Element.removeListener( fn ) //原始fn 1. 从fn的_handlers中删除h的引用 2. 对h调用

    Ext.lib.Event.removeListener Ext.lib.Event.removeListener 1. 找到缓存在listeners中的数据 2. 从listeners将缓存删除 ExtJS1.1 中事件造成的泄露问题
  14. 事件移除 Element.removeAllListener Element.removeAllListener 1. 取得el上的所有listener 2. 对每一个事件函数调用 removeListener this.getListeners( el,

    eventName );//bug 1. 从listenrs中获得el绑定的h 2. 对h调用 Ext.lib.Event.removeListener ExtJS1.1 中事件造成的泄露问题
  15. this.getListeners( el, eventName );//bug 相比removeListener少做了件事情:没有删除掉fn上缓存的h 后果:fn引用h, h引用el 事件移除 Element.removeAllListener ExtJS1.1

    中事件造成的泄露问题 1. 取得el上的所有listener 2. 对每一个事件函数调用 removeListener • IE6下造成泄漏 • fn为非local变量时 el不会销毁
  16. 解决方案 1. 事件绑定时缓存fn 2. 升级到高版本:ExtJS2.2中解决了该问题 ExtJS1.1组件销毁时没有对生成的所有元素做销毁——逐个打补丁 this.getListeners( el, eventName );//bug

    事件移除 Element.removeAllListener ExtJS1.1 中事件造成的泄露问题 1. 取得el上的所有listener 2. 对每一个事件函数调用 removeListener