Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
GC算法和IE中JS内存泄露
Search
xwcoder
December 06, 2012
Technology
2
190
GC算法和IE中JS内存泄露
09、10年用ExtJS1.1做OPOA时整理的一份关于内存泄露的文档。现整理成PPT。
xwcoder
December 06, 2012
Tweet
Share
Other Decks in Technology
See All in Technology
RevOps実践で学んだ俺が最強のデータ基盤になることの重要性 / revops-practice-learned
pei0804
1
860
わいわいClaude Code アイスブレイクLT iOSDC2025 Day2 アンカンファレンス
hiragram
0
100
空間再現力の鍵、APMPを読み解く
ridwy
1
110
Создание мультиагентной системы на базе AI Studio
shwars
0
160
組織を巻き込む大規模プラットフォーム移行戦略 〜50+サービスのマルチリージョン・マルチプロダクト化で学んだステークホルダー協働の実践〜 / Platform migration strategy engaging all stakeholders
toshi0607
2
540
Swift6.2時代のconcurrencyを考える会
yuukiw00w
0
280
iOSDC2025 みてねiOSアプリにおける バックグラウンドアップロード継続の挑戦
hikarusato
2
500
Rust In Python
lycorptech_jp
PRO
3
320
開発用LLMインフラをVSCode内で完結させる
ueponx
1
230
AIを導⼊しても、 開発⽣産性は"爆増"していない なぜ?
kinosuke01
4
2.9k
Goのビルドシステムの変遷 / The history of Go's build system
ymotongpoo
9
1.3k
Breaking the Paywall to Build In-App Purchases Securely
sohsatoh
0
440
Featured
See All Featured
Fireside Chat
paigeccino
40
3.6k
Typedesign – Prime Four
hannesfritz
42
2.8k
KATA
mclloyd
32
14k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.5k
Being A Developer After 40
akosma
90
590k
Gamification - CAS2011
davidbonilla
81
5.4k
Principles of Awesome APIs and How to Build Them.
keavy
127
17k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
31
2.2k
Bash Introduction
62gerente
615
210k
Art, The Web, and Tiny UX
lynnandtonic
303
21k
The World Runs on Bad Software
bkeepers
PRO
71
11k
How GitHub (no longer) Works
holman
315
140k
Transcript
GC算法和IE中JS内存泄露 一点总结
Lisp :对现代软件开发技术贡献最大的语言 •垃圾收集 •数据结构 •人工智能 •并行处理 •虚拟机技术 •元数据技术 •……
J.McCarthy Lisp之父 人工智能之父 M.L.Minsky 1969 图灵奖得主
三大传统算法:Reference Counting (引用计数) obj v1 v2 v3 count: 3 循环引用问题
(从前有座山,山上有座庙,庙里有个老和尚, 老和尚在给小和尚讲故事,讲的啥? 从前有座山,山上有座庙…)
三大传统算法: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 未被标记,回 收 … 未被标记,回 收
三大传统算法:Mark-Sweep (标记-清除) step 1:标记被使用的对象 step 2:清除未被标记的对象 第一个实用完善的GC算法 J.McCarthy 1960 用于lisp
没有循环引用问题 效率问题:早期lisp GC时间占到系统总运行时间的40%
三大传统算法: Copying (复制) 运行 obj1 obj2 obj3 obj4 using using
using GC时 obj1 obj2 obj3 obj4 using using using GC后 obj1 obj2 obj3 obj4 using using using
三大传统算法: Copying (复制) 天才的想法 • 堆空间平均分成两部分,运行程序只使用一部分 • 回收时,使用中的对象复制到另一部分 1. 效率高
2. 没有内存碎片 浪费了一半的空间!!!
理想中的垃圾回收 1. 不暂停程序运行 2. 不占用大量的内存 3. 不占用大量的CPU资源 现代算法都是在三大传统算法基础上努力达到上述三点要求
Mark-Compact (标记-整理) step 1: 标记被使用的对象 step 2: 未标记对象和标记对象向相反方向移动 step 3:
释放未标记对象 • 没有内存浪费 • 效率不错 • 没有内存碎片 结合Mark-Sweep and Copying
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 (串行计算机上的实时表处理技术) 阐述了多进程环境下的增量收集算法
Generational Collecting (分代) 使用统计学 针对不同的内存对象寿命使用不同的策略 1983 H.Lieberman, C.Hewitt A real-time
garbage collector based on the lifetime of objects
那些使用垃圾回收的语言 * 1960 lisp * 1964 Simula * 1969 Smalltalk
* 1970 Prolog * 1973 ML * 1975 Scheme * 1983 Modula-3 * 1986 Eiffel * 1987 Haskell ...... * java, .net, javascript ......
浏览器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()
浏览器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()
何时执行GC IE6 一组阀值: { 256个变量 4096个对象或数组 64K string } 达到其一就执行GC
IE7 默认阀值 同IE6 GC回收率 < 15%,defalut * 2 GC回收率 > 85%,default还原
IE中JS内存泄露现象 之一:循环引用泄露 IE(<=8)中JS对象和COM之间产生循环引用时 IE7修复了此问题 所以,集中体现在IE6中 循环引用 造成泄露
断开循环引用 IE中JS内存泄露现象 之一:循环引用泄露 IE(<=8)中JS对象和COM之间产生循环引用时。 IE7修复了此问题,所以集中体现在IE6中 循环引用 造成泄露
IE中JS内存泄露现象 之一:循环引用泄露 IE(<=8)中JS对象和COM之间产生循环引用时。 IE7修复了此问题,所以集中体现在IE6中 闭包引起的循环引用
google map api 提供了一个函数 用于在页面unload事件中解决闭包带来的 内存泄露问题 IE中JS内存泄露现象 之一:循环引用泄露 IE(<=8)中JS对象和COM之间产生循环引用时。 IE7修复了此问题,所以集中体现在IE6中
闭包引起的循环引用
IE中JS内存泄露现象 之二: Cross-Page Leaks 节点插入顺序 为了child能够知道parent的信息,IE创建了一个临时scope对象, 而这个对象泄露了。页面跳转不释放。 节点插入顺序
微软赖皮行径一 IE中JS内存泄露现象 之二: Cross-Page Leaks 节点插入顺序 为了child能够知道parent的信息,IE创建了一个临时scope对象, 而这个对象泄露了。页面跳转不释放。 节点插入顺序
IE中JS内存泄露现象 之三: innerHTML 造成泄露 正确做法
IE中JS内存泄露现象 之四: Pseudo-Leaks 伪泄露 页面销毁时释放
微软赖皮行径二 IE中JS内存泄露现象 之四: Pseudo-Leaks 伪泄露 页面销毁时释放
建议 • 使用var定义变量,避免错误的定义全局变量 • 全局变量没用时置为null • 正确使用delete,删除一些无用属性 • 正确使用try catch,确保去除无用引用的代码能够被执行
• open出来的窗口即使close 后window对象仍存在的,记得删除引用 • frame和iframe的情况同上
ExtJS1.1 中事件造成的泄露问题 Memory Leak is an important thing, especially in
OPOA especially in OPOA especially in OPOA especially in OPOA
节点移除 ExtJS1.1 中事件造成的泄露问题
节点移除 ExtJS1.1 中事件造成的泄露问题
事件绑定 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 中事件造成的泄露问题
事件移除 Element.removeListener Element.removeAllListener ExtJS1.1 中事件造成的泄露问题
事件移除 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 中事件造成的泄露问题
事件移除 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 中事件造成的泄露问题
事件移除 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 中事件造成的泄露问题
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不会销毁
解决方案 1. 事件绑定时缓存fn 2. 升级到高版本:ExtJS2.2中解决了该问题 ExtJS1.1组件销毁时没有对生成的所有元素做销毁——逐个打补丁 this.getListeners( el, eventName );//bug
事件移除 Element.removeAllListener ExtJS1.1 中事件造成的泄露问题 1. 取得el上的所有listener 2. 对每一个事件函数调用 removeListener
ref http://msdn.microsoft.com/library/default.asp?url=/library/en-us/IETechCol /dnwebgen/ie_leak_patterns.asp http://blogs.msdn.com/b/ericlippert/archive/2003/09/17/53028.aspx http://blogs.msdn.com/b/ericlippert/archive/2003/09/17/53038.aspx http://www.quirksmode.org/blog/archives/2006/04/ie_7_and_javasc.html http://www.ituring.com.cn/article/details/436 http://blog.stchur.com/2007/05/16/ie-innerhtml-memory-leak/
None