内存泄漏
2019-06-28 本文已影响0人
94very
该文章是结合他人文章写下自己的理解,以自己以后继续回来学习而写的。
先了解几个概念
内存
是具有生命周期的,在强类型语言如 C 中则会使用 malloc() 和 free() 等等来管理内存,而 JavaScript 作为一个弱类型语言,其中的内存也是存在生命周期的。
内存的分配
内存的分配是由操作系统进行分配的,但内存的生命周期结束之后便返还给操作系统
内存泄漏
应用程序使用过的内存片段,不再需要了,但没有返还给操作系统或可用池
垃圾回收机制
大多数语言提供自动内存管理,减轻程序员的负担,这被称为"垃圾回收机制"
首先看看 JavaScript 的内存分配
var n = 374;
// 为数字分配内存
var s = 'sessionstack';
// 为字符串分配内存
var o = {
a: 1,
b: null
};
// 为对象及其包含的值分配内存
var a = [1, null, 'str'];
// (如object)为数组及其包含的值分配内存
function f(a) {
return a + 3;
}
// 分配一个函数(它是一个可调用的对象)函数表达式也分配一个对象
someElement.addEventListener('click', function() {
someElement.style.backgroundColor = 'blue';
}, false);
上面介绍了内存泄漏,即没有将不再需要的内存及时返还给操作系统,浏览器为了减少程序员的工作量便会进行垃圾回收机制来回收这些内存,现有的垃圾回收机制有以下两种
1. 引用计数垃圾收集
2. 标记和扫描算法
两种方法都使用了内存引用,在浏览器中对象的访问便会产生引用,语言引擎中会有一张表用来保存引用的关系称为"引用表",下面简单叙述一下两种方式
a-4-2.PNG
1. 引用计数垃圾收集
当一个对象在“引用表”中的引用为零时,便会认为改内存不再被需要,则该对象便会被进行回收,内存返还给操作系统
2. 标记和扫描算法
在 JavaScript 中,以窗口作为根,从根开始检查所有它的子对象并标记,随后,垃圾回收器会回收那些没有被标记的对象,将内存返还给操作系统
上述两种方法中垃圾回收机制的方法会存在循环引用不能回收的问题
循环引用
function f () {
var o1 = {};
var 02 = {};
o1.p = o2;
o2.p = o1;
return true;
}
f();
在上述情况中,o1 和 o2 相互引用,因此造成了每个对象都至少被引用了一次,根据引用计数垃圾收集浏览器便不会自动回收,而必须手动回收释放内存。现在的浏览器都已经发布了垃圾回收器,现在的垃圾收集采用的正是标记和扫描算法。
我所学习的博客,记录于此以便自己日后的学习,在此衷心的感谢各位大佬的博客,公开来可以被使用来学习。
http://www.ruanyifeng.com/blog/2017/04/memory-leak.html
https://juejin.im/post/5a725c6ff265da3e2e62d0d1