简介

本篇文章讲解JavaScript 中垃圾回收机制,内存泄漏,结合一些常遇到的例子,相信各位看完后,会对JS 中垃圾回收机制有个深入的了解。

我的github,欢迎 star

内存生命周期

首先,不管什么程序语言,内存生命周期基本是一致的:

  • 分配你所需要的内存
  • 使用分配到的内存(读、写)
  • 不需要时将其释放归还

在所有语言中第一和第二部分都很清晰。最后一步在低级语言中(C语言等)很清晰,但是在像JavaScript 等高级语言中,这一步是隐藏的、透明的。因为JavaScript 具有自动垃圾收集机制(Garbage collected )。在编写 JS 时,不需要关心内存使用问题,所需内存分配以及无用内存的回收完全实现了自动管理。

内存泄漏

内存泄漏(memory leaks),什么情况下回导致内存泄漏?可以简单理解为有些代码本来要被回收的,但没有被回收,还一直占用着操作系统内存,从而越积越多,最终会导致内存泄漏(可以理解为,内存满了,就溢出了)。

管理内存(Memory Management)

分配给web浏览器的可用内存数量通常要比分配给桌面应用程序少。这样做的目的主要是处于安全方面考虑,目的是防止运行JS 的网页耗尽全部系统内存而导致系统崩溃。内存限制问题不仅会影响给变量分配内存,同时还会影响调用栈以及在一个线程中能够同时执行的语句数量。

因此,确保占用最少的内存可以让页面获得更好的性能。而优化内存占用的最佳方式,就是为执行中的代码只保存必要的数据。一旦数据不再有用,最好通过将其值设置为 null 来释放其引用。这个方法叫做解除引用。这一做法适用于大多数的全局变量和全局对象的属性。局部变量会在他们离开执行环境时自动被解除引用。

解除一个值的引用并不意味着自动回收改值所占用的内存。解除引用的真正作用是让值脱离执行环境,以便垃圾收集器下次运行时将其回收。

标记清除(Mark and Sweep)

通常,垃圾收集器(garbage collector)在运行时候会给储存在内存中的所有变量都加上标记。然后,它会去掉环境中的变量以及被环境中的变量引用的变量的标记。而在此之后再被加上标记的变量将被视为准备删除的变量,原因是环境中的变量已经无法访问到这些变量了。最后,垃圾收集器完成内存清除的工作。

那标记清除具体是如何呢?有以下几种算法:

  • 在JavaScript 中,全局变量(Global)和window 对象会一直存在,不会被垃圾收集器回收;
  • 递归所用到的所有(包括变量和方法),都不会被回收;
  • 所有没有被标记为“活跃(active)”的,都会被认为是垃圾,收集器释放会回收垃圾,并把内存还给操作系统。

例子:

例一:

var n = 123;
// 给数值变量分配内存var s = "azerty";
// 给字符串分配内存// 给对象及其包含的值分配内存
var o = {a: 1,b: null
};// 给函数(可调用的对象)分配内存
function f(a){return a + 2;
}

例二:

function foo(arg) {// 此处bar 是全局变量,window.bar 可以访问,所以也不会被回收bar = "this is a hidden global variable";
} function foo() {// 此处this 代表 windowthis.variable = "potential accidental global";
}

例三:

var someResource = getData();
setInterval(function() {var node = document.getElementById('Node');if(node) {node.innerHTML = JSON.stringify(someResource));}
}, 1000);// 上面这段代码,定时器setInterval 和 someResource 一直存在,不会被回收。可以改成下面代码var element = document.getElementById('button');function onClick(event) {element.innerHtml = 'text';
}element.addEventListener('click', onClick);
// 手动移除事件监听器和变量
element.removeEventListener('click', onClick);
element.parentNode.removeChild(element);

例四:

var intervalId = null, params;function createChunks() {var div, foo, i, str;for (i = 0; i < 20; i++) {div = document.createElement("div");str = new Array(1000000).join('x');foo = {str: str,div: div};div.foo = foo;}
}function start() {if (intervalId) {return;}intervalId = setInterval(createChunks, 1000);
}function stop() {if (intervalId) {// 清除定时器clearInterval(intervalId);}// 清除变量intervalId = null;
}

链接观察垃圾回收是怎么工作的—Google: Watching the GC work

在上面图片中,可以观察到,点击 start 按钮,内存和节点数暴增,当点击stop 时,垃圾收集器回收了这些定时器、变量等,从而释放了内存。

上期博客

  • 重构你的JS代码
  • 一些CSS3动画

我的github,欢迎star

深入浅出 JavaScript 内存管理,垃圾回收相关推荐

  1. 深入浅出JVM内存模型+垃圾回收算法

    文章目录 前言 JVM内存模型 1. 程序计数器(记录当前线程) 2. Java栈(虚拟机栈) 3. 本地方法栈 4. 堆 5.方法区 6.直接内存 JVM垃圾回收 垃圾判断标准 1. 引用计数法 2 ...

  2. PHP内存管理 垃圾回收

    来源:http://www.jianshu.com/p/63a381a7f70c 概述 1) 操作系统直接管理着内存,所以操作系统也需要进行内存管理,计算机中通常都有内存管理单元(MMU) 用于处理C ...

  3. python内存回收垃圾有哪些_[Python之路] 内存管理垃圾回收

    一.python源码 1.准备源码 解压得到文件夹: 我们主要关注Include中的".h"文件以及Objects目录中的".c"文件. 我们从Include和 ...

  4. python内存管理垃圾回收原理

    "  引用计数器 为主, 标记清除 和 分代回收 为

  5. JavaScript 中的垃圾回收和内存泄露如何处理?| 技术头条

    作者 | 浪里行舟 责编 | 郭芮 程序的运行需要内存.只要程序提出要求,操作系统或者运行时就必须供给内存.所谓的内存泄漏简单来说是不再用到的内存,没有及时释放.为了更好避免内存泄漏,我们先介绍Jav ...

  6. JavaScript中的垃圾回收和内存泄漏

    前言 程序的运行需要内存.只要程序提出要求,操作系统或者运行时就必须供给内存.所谓的内存泄漏简单来说是不再用到的内存,没有及时释放.为了更好避免内存泄漏,我们先介绍Javascript垃圾回收机制. ...

  7. 【转】JavaScript 中的垃圾回收和内存泄露如何处理

    转自 https://blog.csdn.net/csdnnews/article/details/89596750?ops_request_misc=%257B%2522request%255Fid ...

  8. javaScript 内存管理机制

    大家好,今天分享的主题为 JavaScript 内存管理机制,本次分享将从以下三部分进行讲述: js 内存管理与 js 垃圾 常见的 GC 算法 V8 引擎的垃圾回收 js 内存管理与 js 垃圾 关 ...

  9. JVM 上篇之内存与垃圾回收(个人笔记,勿看)

    内存与垃圾回收篇 字节码与类的加载篇 性能监控与调优篇 大厂面试篇 文章目录 JVM 跨语言的平台 虚拟机与Java虚拟机 虚拟机 Java 虚拟机 Java 代码的执行流程 JVM的架构模型 JVM ...

最新文章

  1. Vyond制作2D动画学习教程
  2. 零配置Socket TCP消息通讯服务容器EC
  3. convert.todatetime指定日期格式_JDK1.8新增日期时间类型
  4. ROS中自定义复杂数据类型
  5. linux向用户发送消息
  6. 拖拽上传及读取文件实现
  7. 空格在科技类文章中对阅读体验的影响
  8. java怎么改运行图标,java修改进程图标
  9. Linux部署东方通TongWeb7
  10. unipush配置华为通道
  11. 数据分析之描述性统计分析
  12. 字体图标文件服务器提示404,iis环境下字体图标woff/woff2/svg返回404不显示的原因与解决方法...
  13. 如何使单片机复位可靠,单片机复位电路?
  14. 鸿蒙系统可以微信吗,“微信”跟鸿蒙系统,只能选择一个,华为尴尬了
  15. 原码、反码、补码、移码存在的意义
  16. 异常处理(六)--------SpringBoot+Maven项目运行异常:Unable to find a single main class from the following candidat
  17. 使用Pycharm设置python脚本文件头
  18. 并查集的使用,臭虫同性恋问题
  19. Android 声音分贝控制锁屏demo实现
  20. 微信小程序--证件照换底色UI及前端页面修改+札记与贺卡图片整理

热门文章

  1. 运维学习之进程的定义及其命令的使用
  2. ENode 2.0 - 深入分析ENode的内部实现流程和关键地方的幂等设计
  3. Spring MVC笔记 添加错误页面
  4. ansible安装配置及实例
  5. php 获取网卡mac
  6. 二叉搜索树的经典问题
  7. 被迫学计算机,电脑强迫人学习
  8. 计算机和电子音乐之间的关系,浅析计算机音乐中算法作曲的特点及及作曲技法的对应关系.doc...
  9. linux编译安装madam,linux 下 使用 mdadm 创建阵列
  10. explain分析执行计划