Mai*_*pal 30 javascript internet-explorer garbage-collection memory-leaks circular-reference
请考虑Mozilla Docs关于JavaScript内存泄漏的这句话:
Run Code Online (Sandbox Code Playgroud)function addHandler() { var el = document.getElementById('el'); el.onclick = function() { this.style.backgroundColor = 'red'; } }上面的代码将元素设置为在单击时变为红色.它还会造成内存泄漏.为什么?因为对el的引用无意中被捕获到为匿名内部函数创建的闭包中.这将在JavaScript对象(函数)和本机对象(el)之间创建循环引用.
请以简单明了的方式解释上述泄漏的原因,我没有得到确切的观点.
由于泄漏,网站/页面是否面临安全问题?我该如何避免它们?其他什么代码会导致内存泄漏?如何判断内存泄漏的时间?
我是内存泄漏主题的绝对新手.有人可以一步一步地为我澄清这些东西吗?还有人可以帮我澄清这句话"这会在JavaScript对象(函数)和本机对象(el)之间创建一个循环引用."
gki*_*ely 19
有两个概念可以帮助您理解这个示例.
1)关闭
闭包的定义是每个内部函数都可以访问其父函数变量和参数.
当addHandler()函数结束时,匿名函数仍然可以访问父的变量el.
2)功能=记忆
每次定义function新对象时都会创建.是什么让这个例子有点混乱,onclick是一个只能设置为DOM元素一次的事件.
那么肯定el.onclick = function(){};会覆盖旧功能吧?
错误!每次addHandler运行时,都会创建一个新的函数对象.
结论:
每次函数运行时,它都会创建一个新对象,其中包含一个闭包el.看到匿名函数维护访问权限el,垃圾收集器无法将其从内存中删除.
anon函数将保持对el的访问,并且el可以访问该函数,即循环引用,这会导致IE中的内存泄漏.
无论何时在JavaScript中定义函数,都会为其创建执行上下文 ; 此执行上下文包含对作用域链中所有变量的引用,从全局作用域一直到本地作用域:
function test()
{
var el = document.getElementById('el');
el.onclick = function() {
// execution context of this function: el, test
alert('hello world');
}
}
Run Code Online (Sandbox Code Playgroud)
当test()完成后,匿名功能尚未回收,因为它现在分配给DOM的元素; 即它被DOM元素的属性引用.
同时,DOM元素本身也是函数执行上下文的一部分,现在由于循环引用而无法再循环,即使实际使用它并不是很明显; 你可以在这个答案中找到一个演示.
也就是说,如今,大多数JavaScript引擎(甚至是那些在IE中找到的引擎)使用更高级的垃圾收集器,可以使用标记和清除或生成/短暂垃圾收集等技术更好地识别未使用的变量.
为了确保您不会在任何浏览器上遇到问题(但是,由于页面的典型生命周期,这主要是理论上的):
document.getElementById('el').onclick = function() {
alert('hello world');
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2996 次 |
| 最近记录: |