We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
作为一种高级语言,JS 负责几个低级别的管理,比如内存管理。对于大多数编程语言来说,垃圾回收是一个常见的过程。通俗地说,垃圾回收就是简单地收集和释放,那些已经分配给对象,但目前又不被程序任一部分使用的内存。在像 C 这样的编程语言中,开发者必须使用 malloc() 和 dealloc() 函数来处理内存分配和回收。 Javascript 具有自动垃圾回收机制,会定期对那些我们不再使用的变量、对象所占用的内存进行释放。
Javascript 会找出不再使用的变量,不再使用意味着这个变量生命周期的结束。Javascript 中存在两种变量——全局变量和局部变量,全部变量的声明周期会一直持续,直到页面卸载。而局部变量声明在函数中,它的声明周期从执行函数开始,直到函数执行结束。在这个过程中,局部变量会在堆或栈上被分配相应的空间以存储它们的值,函数执行结束,这些局部变量也不再被使用,它们所占用的空间也就被释放。
但是有一种情况的局部变量不会随着函数的结束而被回收,那就是局部变量被函数外部的变量所使用,其中一种情况就是闭包,因为在函数执行结束后,函数外部的变量依然指向函数内的局部变量,此时的局部变量依然在被使用,所以也就不能够被回收
JavaScript 中内存管理的主要概念是可达性。
简单地说,“可达性” 值就是那些以某种方式可访问或可用的值,它们被保证存储在内存中。
本地函数的局部变量和参数
当前嵌套调用链上的其他函数的变量和参数
全局变量
还有一些其他的,内部的
这些值称为根。
例如,如果局部变量中有对象,并且该对象具有引用另一个对象的属性,则该对象被视为可达性, 它引用的那些也是可以访问的。
JavaScript 引擎中有一个后台进程称为垃圾回收器,它监视所有对象,并删除那些不可访问的对象。
引用计数法就是引用对引用的次数进行计数。如果引用了增加就加 1,引用减少就减去 1。当引用等于 0 时将它清除。
引用计数有一个致命的问题就是循环引用,如果两个对象互相引用,尽管不再使用但是会进入一个无限循环,垃圾回收器不会对他进行回收。现在一般不会使用这个方法,但是 ie9 之前仍然还在用。
标记清除算法是目前使用的较多的方法
基本的垃圾回收算法称为标记-清除,定期执行以下“垃圾回收”步骤:
例如,对象结构如下:
我们可以清楚地看到右边有一个“不可到达的块”。现在让我们看看“标记并清除”垃圾回收器如何处理它。
标记清除法利用到了堆、链表结构 标记阶段:从根集合出发,将所有活动对象及其子对象打上标记 清除阶段:遍历堆,将非活动对象(未打上标记)的连接到空闲链表上
本质上讲,内存泄露就是不再被需要的内存,由于某种原因,无法被释放。
尽量不要使用全局变量。
使用玩及时清理定时器和回调函数。
可以使用 WeakMap 或者 WeakSet 存储 DOM节点,DOM 被移除掉 WeakMap 或者 WeakSet 内部的 DOM 引用会被自动回收清除。
尽管垃圾回收是 JavaScript 自动执行的,但在某些情况下,它可能并不完美。在 JavaScript ES6 中,Map 和 Set 与它们的“weaker”兄弟元素一起被引入。“weaker”对应着 WeakMap 和 WeakSet,持有的是每个键对象的“弱引用”。它们允许对未引用的值进行垃圾收集,从而防止内存泄漏。
The text was updated successfully, but these errors were encountered:
Sorry, something went wrong.
No branches or pull requests
Javascript 的垃圾回收机制
Javascript 会找出不再使用的变量,不再使用意味着这个变量生命周期的结束。Javascript 中存在两种变量——全局变量和局部变量,全部变量的声明周期会一直持续,直到页面卸载。而局部变量声明在函数中,它的声明周期从执行函数开始,直到函数执行结束。在这个过程中,局部变量会在堆或栈上被分配相应的空间以存储它们的值,函数执行结束,这些局部变量也不再被使用,它们所占用的空间也就被释放。
但是有一种情况的局部变量不会随着函数的结束而被回收,那就是局部变量被函数外部的变量所使用,其中一种情况就是闭包,因为在函数执行结束后,函数外部的变量依然指向函数内的局部变量,此时的局部变量依然在被使用,所以也就不能够被回收
可达性
JavaScript 中内存管理的主要概念是可达性。
简单地说,“可达性” 值就是那些以某种方式可访问或可用的值,它们被保证存储在内存中。
1. 有一组基本的固有可达值,由于显而易见的原因无法删除。例如:
本地函数的局部变量和参数
当前嵌套调用链上的其他函数的变量和参数
全局变量
还有一些其他的,内部的
这些值称为根。
2. 如果引用或引用链可以从根访问任何其他值,则认为该值是可访问的。
例如,如果局部变量中有对象,并且该对象具有引用另一个对象的属性,则该对象被视为可达性, 它引用的那些也是可以访问的。
JavaScript 引擎中有一个后台进程称为垃圾回收器,它监视所有对象,并删除那些不可访问的对象。
垃圾回收的算法
引用计数法
引用计数法就是引用对引用的次数进行计数。如果引用了增加就加 1,引用减少就减去 1。当引用等于 0 时将它清除。
引用计数有一个致命的问题就是循环引用,如果两个对象互相引用,尽管不再使用但是会进入一个无限循环,垃圾回收器不会对他进行回收。现在一般不会使用这个方法,但是 ie9 之前仍然还在用。
标记清除算法
基本的垃圾回收算法称为标记-清除,定期执行以下“垃圾回收”步骤:
例如,对象结构如下:
我们可以清楚地看到右边有一个“不可到达的块”。现在让我们看看“标记并清除”垃圾回收器如何处理它。
标记清除算法数据结构
内存泄露
本质上讲,内存泄露就是不再被需要的内存,由于某种原因,无法被释放。
常见的内存泄露案例
参考资料
The text was updated successfully, but these errors were encountered: