垃圾回收
- js的垃圾自动回收机制,就是找到不被使用的值,将其占用的内存释放掉。
引用计数
- 现代游览器已不在使用引用计数,Ie9以下的游览器仍在使用。
- 引用计数,即查看对象是否存在指向他的引用,如果没有则释放掉。
var a = { a: 1 };
var c = a;
上面这一段代码,{a:1} 被a,b应用了两次,将 a = null, b = null 时 { a: 1 } 才会被释放掉
- 这种回收机制无法释放一些无效但是存在引用的对象(循环引用)
function test (){
var a = { ax: 1 };
var b = { bx: 2 };
a.bx = b;
b.ax = a;
......
}
执行test()时:
理想:test执行开始时候,会给其中定义的变量划分内存空间保存,以备后面的语句使用,等函数执行完毕返回了这些变量被认为无用的了,对应的空间也就收回了,下次执行此函数的时候,所有变量回到初始状态,重新赋值使用。
现实:test执行后,本应该释放的a,b发现a被b引用,b被a引用。他们引用次数大于0不会被垃圾回收,内存泄漏。
下面是一段常用的
var div = document.getElementById('test')
div.onClick = function () { }
div有事件处理函数的引用,同时事件处理函数也有div的引用!(div变量可在函数内被访问) 一个循环引用形成
标记清楚
- 简单来说就是根部(全局)触达,凡是不能通过根部找到的将会被释放掉。
- 从根部开始访问并标记他们(同时防止用一个对象重复遍历),最后将未有标记的清除掉。
内存泄漏
- 简单来说就是一些不在使用的值,仍占据内存没有被回收掉就会造成内存泄漏。
- 原因:存在不需要的引用
常见的内存泄漏
意外的全局变量
function () {
a = 'test'
}
function () {
this.a = 'test'
}
- 函数内部用了为声明的变量a或this.a,即 window.a = 'test'
- 在函数使用变量时,根据需求避免一些非必要的全局声明
遗漏的定时器
var n = 1
setInterval(() => {
if(n < 2000){
n++
}
}, 1000)
- 当n>=2000后没有清除定时器
DOM操作
<body>
<button onclick="re()">remove</button>
<ul id='par' class="p">
<li id="c">1111</li>
</ul>
</body>
<script>
var li = document.getElementById('c');
function re() {
// 移除 ul的dom节点
document.body.removeChild(document.getElementById('par'))
// 通过li查找父节点
console.log(li.parentNode)
}
</script>
- 当声明一个li并指向一个DOM节点后,即使将DOM整个删除(父级),通过这个声明我仍能通过这个引用(li)找回整个已经被删除的DOM树
- 除必要情况下,DOM操作要做到用后即焚。
闭包
function onclick(){
let btn = document.getElementById("button");
obj.onclick=function(){
//.
}
}
- 函数内部定义了一个变量,这个变量的事件引用了内部函数,并且这个事件回调函数的引用外暴了,形成闭包.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。