JavaScript内存管理

更新日期: 2019-11-27阅读: 1.8k标签: 内存

垃圾回收

垃圾回收:在不需要字符串、对象的时候,需要释放其所占用的内存。

高级语言解释器嵌入了“垃圾回收器”,监控着所有对象,当对象生存周期结束时会将其删除。
内嵌的垃圾回收器的问题:自动寻找是否一些内存“不再需要”的问题是无法判定的。垃圾回收实现只能有限制的解决一般问题。所以引出垃圾回收算法(机制)。

垃圾回收算法

垃圾回收算法主要依赖于引用的概念。在内存管理的环境中,一个对象如果有访问另一个对象的权限(隐式或者显式),叫做一个对象引用另一个对象。例如,一个Javascript对象具有对它原型的引用(隐式引用)和对它属性的引用(显式引用)。

在这里,“对象”的概念不仅特指 JavaScript 对象,还包括函数作用域(或者全局词法作用域)。

垃圾回收算法~~~~的原理:垃圾收集器会按照固定的时间间隔,周期性的找出不再继续使用的变量,然后释放其占用的内存。
不再使用的变量也就是生命周期结束的变量,是局部变量,局部变量只在函数的执行过程中存在,当函数运行结束,没有其他引用(闭包),那么该变量会被标记回收。全局变量不会被当成垃圾回收。

“标记-清除算法”

工作原理:
当变量进入环境时(例如在函数中声明一个变量),将这个变量标记为“进入环境”,当变量离开环境时,则将其标记为“离开环境”。标记“离开环境”的就回收内存。

工作流程:

  1. 垃圾收集器会在运行的时候会给存储在内存中的所有变量都加上标记。
  2. 去掉环境中的变量以及被环境中的变量引用的变量的标记。
  3. 那些还存在标记的变量被视为准备删除的变量。
  4. 最后垃圾收集器会执行最后一步内存清除的工作,销毁那些带标记的值并回收它们所占用的内存空间。
引用计数算法:被废弃的垃圾收集策略


内存泄露

内存泄漏:未能释放不再使用的内存,造成内存的浪费。
  • 即使是1byte的内存,也叫内存泄漏,并不一定是导致浏览器崩溃、卡顿才能叫做内存泄漏。
  • 一般是堆区内存泄漏,栈区不会泄漏。
  • 基本类型的值存在内存中,被保存在栈内存中,引用类型的值是对象,保存在堆内存中。所以对象、数组之类的,才会发生内存泄漏。

哪些情况会引起内存泄漏?

虽然有垃圾回收机制,但我们在编写代码的时候,有些情况还是会造成内存泄漏,了解这些情况,并在编写程序的时候,注意避免,我们的程序会更具健壮性。

意外的全局变量:

全局变量不会被当成垃圾回收,我们在编码中有时会出现下面这种情况:

    function foo() {
     this.bar2 = '默认绑定this指向全局' // 全局变量=> window.bar2
      bar = '全局变量'; // 没有声明变量 实际上是全局变量=>window.bar
    }
    foo();

当我们使用默认绑定,this会指向全局,this.something也会创建一个全局变量,这一点可能很多人没有注意到。

解决方法:
1. 在函数内使用严格模式

    function foo() {
      "use strict"; 
      this.bar2 = "严格模式下this指向undefined"; 
      bar = "报错";
    }
    foo();

2.手动释放全局变量的内存

    window.bar = undefined
    delete window.bar2
被遗忘的定时器和回调函数

不需要setInterval或者setTimeout时,定时器没有被clear,定时器的回调函数以及内部依赖的变量都不能被回收,造成内存泄漏。

var someResource = getData();
setInterval(function() {
    var node = document.getElementById('Node');
    if(node) {
        node.innerhtml = JSON.stringify(someResource));
        // 定时器也没有清除
    }
    // node、someResource 存储了大量数据 无法回收
}, 1000);

解决方法: 在定时器完成工作的时候,手动清除定时器。

闭包:

闭包可以维持函数内局部变量,使其得不到释放,造成内存泄漏

    function bindEvent() {
      var obj = document.createElement("XXX");
      var unused = function () {
          console.log(obj,'闭包内引用obj obj不会被释放');
      };
      // obj = null;
    }

解决方法:手动解除引用,obj = null。

没有清理dom元素引用:
    var refA = document.getElementById('refA');
    document.body.removeChild(refA); // dom删除了
    console.log(refA, "refA");  // 但是还存在引用 能console出整个div 没有被回收

不信的话,可以看下这个dom点击预览。

解决办法:refA = null;

console保存大量数据在内存中。

过多的console,比如定时器的console会导致浏览器卡死。

解决办法:合理利用console,线上项目尽量少的使用console。


链接: https://fly63.com/article/detial/7949

JavaScript 内存管理和垃圾回收

JavaScript 的内存管理和垃圾回收,是个略生僻的话题,因为在JavaScript 中不显式执行内存操作,不过最好了解它如何工作。

js常见的内存泄漏及解决方法总汇

js具有自动回收垃圾的机制,即执行环境会负责管理程序执行中使用的内存。在C和C++等其他语言中,开发者的需要手动跟踪管理内存的使用情况。在编写js代码时候,开发人员不用再关心内存使用的问题,所需内存的分配 以及无用的回收完全实现了自动管理。

浅谈javaScript内存机制

javaScript内存空间并不是一个经常被提及的概念,想要对JS的理解更加深刻,就必须对内存空间有一个清晰的认:栈与堆、复杂数据类型与基本数据类型、引用数据类型与堆内存

js 把一个对象赋值给另一个对象会指向同一个内存地址

实际上并不是新建一个和原对象(数组也是对象)完全一样的对象,而是把原对象的内存地址直接复制给了另一个对象,也就是说两个对象都是指向同一个内存地址,所以实际上它们就是同一个对象。

php底层原理之垃圾回收机制

php垃圾回收机制,对于PHPer来说是一个不陌生但是又不是很熟悉的内容。那么php是怎么实现对不需要的内存进行回收的呢?首先还是需要了解下基础知识,便于垃圾回收原理内容的理解。

js变量、作用域和内存问题

JavaScript变量可以用来保存两种类型的值:基本类性值和引用类性值。所有变量(包括基本类型和引用类型)都存在于一个执行环境(也称为作用域)当中,具有自动垃圾收集机制的编程语言,开发人员不必关心内存分配和回收问题

php中的内存管理

计算机的内存由操作系统进行管理,所以普通应用程序是无法直接对内存进行访问的。应用程序只能向操作系统申请内存,通常的应用也是这么做的,在需要的时候通过类似malloc之类的库函数 向操作系统申请内存。

原生JS与Jquery删除iframe并释放内存-IE

当项目以tab页签方式打开多个iframe窗口时,关闭tab页签同时也需要关闭iframe并释放内存资源,主要是针对IE浏览器。

闭包真的会导致内存泄漏?

今天遇到一个很有争议的问题,在这里分享一下,我相信对于即将面试前端的小伙伴会有帮助的。主要内容是围绕下边的问题展开的,文章涉及到的其他方面的知识点不展开叙述。

Web 应用的内存优化

随着 Web 应用复杂程度越来越高,以及 NodeJS 大规模投入生产环境,许多 Web 应用都会长时间运行, JavaScript 的内存管理显得更为重要。JavaScript 具备自动回收垃圾的机制

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!