今天总结下js的回收机制。前端
提及js的回收机制,必定要先说js的内存分配了。浏览器
前端的同窗们确定知道,js的变量分为基本类型和引用类型。安全
为何内存还要区分堆内存和栈内存呢?这里就要说到js的垃圾回收机制了。闭包
为何会有垃圾回收呢?固然是为了使程序运行时的内存最小啦。性能
当一个方法执行的时候,会有部份内存用来存方法中声明的变量,这些变量都被存在栈内存中,当方法结束的时候,这个栈内存中的变量(除了地址之外)都会被销毁。优化
可是当咱们声明一个对象的时候,这个对象在其余地方也被引用了,这个对象的大小是不固定的,会被分配到堆内存中,随着方法的结束,这个堆内存也不会被销毁,由于其余地方还在引用(方法的传参等等),除非这个对象的引用为0,垃圾回收机制才会在核实以后销毁他,这里就牵扯到了垃圾回收中的引用计数,下面会讲到。操作系统
内存声明周期:线程
在js中,第三部分是自动完成的,由于js中有自动垃圾回收机制。在编写js时,不须要关心内存的使用问题,所需内存的分配和内存的释放都是自动完成的。对象
什么状况下会内存泄漏?能够这么理解,就是有些代码原本应该要被回收的,可是没有被回收,因此一直占用着操做系统的内存,从而越积越多。通常的内存泄漏其实可有可无,可怕的是内存泄漏引发的堆积,致使GC一直没办法使用所占用的内存给其余程序使用。递归
内存溢出就是程序向系统申请必定大小的内存,可是系统知足不了。
处于安全的考虑,通常状况下系统给浏览器的内存会比给客户端的内存要少,即便浏览器内存泄漏了或者内存溢出了也不会让系统崩溃。内存限制的问题不只会影响到给变量分配的内存,也会影响每一个线程最多能执行的语句数量。
因此为了确保在有限的内存中可让页面得到最好的性能,优化内存占用的最佳方式就是将其值设置为null来释放其引用。这个方法叫作解除引用,适用于全局变量和全局对象的属性,局部变量在离开执行环境以后就会自动被解除引用。
解除引用并不意味着立刻回收该值所占用的内存,解除引用的真正做用是让值离开执行环境,让GC下次运行时自动将其回收。
js的垃圾回收通常有两种,标记清除和引用计数。
GC在运行时会给储存在内存中的全部变量加上标记,而后会去掉环境中的变量和被环境中的变量引用的变量的标记,在此以后被加上标记的变量被视为要删除的变量。而后GC完成内存清除。
标记清除会遵循如下几种状况:
当对象被引用次数为0时,就被回收。潜在的一个问题是:循环引用时,两个对象都至少被引用了一次,将不能自动被回收。因此致使,咱们常讲的内存泄露。