js回收机制

今天总结下js的回收机制。前端

提及js的回收机制,必定要先说js的内存分配了。浏览器

内存分配

前端的同窗们确定知道,js的变量分为基本类型和引用类型。安全

  • 基本类型
    js的基本类型有String,Number,Boolean,Null,Undefined,这些变量在内存中占用固定的空间大小,声明以后会被分配到栈内存中,咱们是按值访问的。
  • 引用类型
    js的引用类型的值大小是不固定的,须要经过引用来找到相应的值,在栈内存中会分配空间存放引用类型在堆内存中的地址,在堆内存中会存放对应的值。由于地址的大小是固定的,因此能够存在栈内存中,须要用到的时候,会到栈内存中先找到这个引用地址,而后再在堆中找到这个值。

为何内存还要区分堆内存和栈内存呢?这里就要说到js的垃圾回收机制了。闭包

为何会有垃圾回收呢?固然是为了使程序运行时的内存最小啦。性能

当一个方法执行的时候,会有部份内存用来存方法中声明的变量,这些变量都被存在栈内存中,当方法结束的时候,这个栈内存中的变量(除了地址之外)都会被销毁。优化

可是当咱们声明一个对象的时候,这个对象在其余地方也被引用了,这个对象的大小是不固定的,会被分配到堆内存中,随着方法的结束,这个堆内存也不会被销毁,由于其余地方还在引用(方法的传参等等),除非这个对象的引用为0,垃圾回收机制才会在核实以后销毁他,这里就牵扯到了垃圾回收中的引用计数,下面会讲到。操作系统

内存声明周期

内存声明周期:线程

  1. 分配你所须要的内存
  2. 使用分配到的内存读和写
  3. 不须要时将其释放

在js中,第三部分是自动完成的,由于js中有自动垃圾回收机制。在编写js时,不须要关心内存的使用问题,所需内存的分配和内存的释放都是自动完成的。对象

内存泄漏

什么状况下会内存泄漏?能够这么理解,就是有些代码原本应该要被回收的,可是没有被回收,因此一直占用着操做系统的内存,从而越积越多。通常的内存泄漏其实可有可无,可怕的是内存泄漏引发的堆积,致使GC一直没办法使用所占用的内存给其余程序使用。递归

内存溢出

内存溢出就是程序向系统申请必定大小的内存,可是系统知足不了。

管理内存

处于安全的考虑,通常状况下系统给浏览器的内存会比给客户端的内存要少,即便浏览器内存泄漏了或者内存溢出了也不会让系统崩溃。内存限制的问题不只会影响到给变量分配的内存,也会影响每一个线程最多能执行的语句数量。

因此为了确保在有限的内存中可让页面得到最好的性能,优化内存占用的最佳方式就是将其值设置为null来释放其引用。这个方法叫作解除引用,适用于全局变量和全局对象的属性,局部变量在离开执行环境以后就会自动被解除引用。

解除引用并不意味着立刻回收该值所占用的内存,解除引用的真正做用是让值离开执行环境,让GC下次运行时自动将其回收。

垃圾回收

js的垃圾回收通常有两种,标记清除和引用计数。

标记清除

GC在运行时会给储存在内存中的全部变量加上标记,而后会去掉环境中的变量和被环境中的变量引用的变量的标记,在此以后被加上标记的变量被视为要删除的变量。而后GC完成内存清除。
标记清除会遵循如下几种状况:

  1. 在js中,全局变量和window对象会一直存在,不会被GC回收
  2. 递归所用到的全部方法和变量,不会被GC回收
  3. 闭包里用到的变量,不会被GC回收
  4. 全部被标记的,都被认为是垃圾,GC会启动其回收机制,释放内存。

引用计数

当对象被引用次数为0时,就被回收。潜在的一个问题是:循环引用时,两个对象都至少被引用了一次,将不能自动被回收。因此致使,咱们常讲的内存泄露。

相关文章
相关标签/搜索