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
フロントエンド開発者のための「厄払い」
optim
0
170
オープンウェイトのLLMリランカーを契約書で評価する / searchtechjp
sansan_randd
0
130
2026/01/16_実体験から学ぶ 2025年の失敗と対策_Progate Bar
teba_eleven
1
220
Git Training GitHub
yuhattor
1
270
GitHub Copilot CLI 現状確認会議
torumakabe
12
4.7k
AI開発の落とし穴 〜馬には乗ってみよAIには添うてみよ〜
sansantech
PRO
9
3.9k
人はいかにして 確率的な挙動を 受け入れていくのか
vaaaaanquish
4
2.6k
[Iceberg Meetup #4] ゼロからはじめる: Apache Icebergとはなにか? / Apache Iceberg for Beginners
databricksjapan
0
450
AI アクセラレータチップ AWS Trainium/Inferentia に 今こそ入門
yoshimi0227
1
320
CodeRabbit CLI + Claude Codeの連携について
oikon48
1
650
Regional_NAT_Gatewayについて_basicとの違い_試した内容スケールアウト_インについて_IPv6_dual_networkでの使い分けなど.pdf
cloudevcode
1
140
かわいい身体と声を持つ そういうものに私はなりたい
yoshimura_datam
0
480
Featured
See All Featured
Tips & Tricks on How to Get Your First Job In Tech
honzajavorek
0
420
AI Search: Where Are We & What Can We Do About It?
aleyda
0
6.9k
Leadership Guide Workshop - DevTernity 2021
reverentgeek
1
190
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
234
17k
Crafting Experiences
bethany
1
37
Bridging the Design Gap: How Collaborative Modelling removes blockers to flow between stakeholders and teams @FastFlow conf
baasie
0
440
GraphQLとの向き合い方2022年版
quramy
50
14k
Context Engineering - Making Every Token Count
addyosmani
9
630
The Pragmatic Product Professional
lauravandoore
37
7.1k
Game over? The fight for quality and originality in the time of robots
wayneb77
1
89
Information Architects: The Missing Link in Design Systems
soysaucechin
0
750
From π to Pie charts
rasagy
0
120
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