JavaScript常见几种的内存泄漏

javascript栏目教程介绍常见的内存泄漏

JavaScript常见几种的内存泄漏

前言1 介绍2 内存泄露的主要原因3 常见的内存泄露3.1 全局变量3.2 计时器3.3 多处引用3.4 闭包4 Chrome内存分析工具资料

前言

在阅读这篇博客之前,你或许需要具备一些JavaScript内存管理的知识:

V8中JavaScript的内存管理与垃圾回收

1 介绍

内存泄露(Memory Leaks):是指应用程序已经不再需要的内存,由于某种原因未返回给操作系统或者空闲内存池(Pool of Free Memory)。

内存泄露可能带来的问题:变慢、卡顿、高延迟。

2 内存泄露的主要原因

JavaScript内存泄漏的主要原因在于一些不再需要的引用(Unwanted References)。

所谓的Unwanted References指的是:有一些内存,其实开发人员已经不再需要了,但是由于某种原因,这些内存仍然被标记并保留在活动根目录树中。Unwanted References就是指对这些内存的引用。在JavaScript上下文中,Unwanted References是一些不再使用的变量,这些变量指向了原本可以释放的一些内存。

3 常见的内存泄露

3.1 全局变量

首先,我们得知道,JavaScript中的全局变量是由根节点(root node)引用的,因此它们在应用程序的整个生命周期中都不会被垃圾回收。

场景一:在JavaScript中,如果引用未声明的变量,将会导致,在全局环境中创建新的变量。

function foo(arg) {    bar = "this is a hidden global variable";}

登录后复制

上面这串代码,实际上如下:

function foo(arg) {   window.bar = "this is an explicit global variable";}

登录后复制

假如,我们希望bar这个变量仅在foo函数作用域内部使用,但上面这种情况就会意外地在全局作用域内创建bar,这将造成内存泄漏。

场景二:

function foo() {    this.variable = "potential accidental global";}foo();

登录后复制

同样的,如果我们希望bar这个变量仅在foo函数作用域内部使用,但如果不知道foo函数内部的this指向全局对象,将造成内存泄露。

建议:

避免意外地创建全局变量。比如,我们可以使用严格模式,则本节的第一段代码将报错,而不会创建全局变量。

减少创建全局变量。

如果必须使用全局变量来存储大量数据,请确保在处理完数据后将其置null或重新分配。

3.2 计时器

场景举例:

for (var i = 0; i 

3.3 多处引用

多处引用(Multiple references):当多个对象均引用同一对象时,但凡其中一个引用没有清除,都将导致被引用对象无法GC。

场景一:

var elements = {    button: document.getElementById('button'),    image: document.getElementById('image'),    text: document.getElementById('text')};function doStuff() {    image.src = 'http://some.url/image';    button.click();    console.log(text.innerHTML);    // Much more logic}function removeButton() {    // The button is a direct child of body.    document.body.removeChild(document.getElementById('button'));    // At this point, we still have a reference to #button in the global    // elements dictionary. In other words, the button element is still in    // memory and cannot be collected by the GC.s}

登录后复制

在上面这种情况中,我们对#button的保持两个引用:一个在DOM树中,另一个在elements对象中。 如果将来决定回收#button,则需要使两个引用均不可访问。在上面的代码中,由于我们只清除了来自DOM树的引用,所以#button仍然存在内存中,而不会被GC。

场景二:如果我们想要回收某个table,但我们保持着对这个table中某个单元格(cell)的引用,这个时候将导致整个table都保存在内存中,无法GC。

3.4 闭包

闭包(Closure):闭包是一个函数,它可以访问那些定义在它的包围作用域(Enclosing Scope)里的变量,即使这个包围作用域已经结束。因此,闭包具有记忆周围环境(Context)的功能。

场景举例:

var newElem;function outer() {   var someText = new Array(1000000);   var elem = newElem;   function inner() {       if (elem) return someText;   }    return function () {}; }setInterval(function ()  {   newElem = outer();}, 5);

登录后复制

在这个例子中,有两个闭包:一个是inner,另一个是匿名函数function () {}。其中,inner闭包引用了someText和elem,并且,inner永远也不会被调用。可是,我们需要注意:相同父作用域的闭包,他们能够共享context。 也就是说,在这个例子中,inner的someText和elem将和匿名函数function () {}共享。然而,这个匿名函数之后会被return返回,并且赋值给newElem。只要newElem还引用着这个匿名函数,那么,someText和elem就不会被GC。

同时,我们还要注意到,outer函数内部执行了var elem = newElem;,而这个newElem引用了上一次调用的outer返回的匿名函数。试想,第n次调用outer将保持着第n-1次调用的outer中的匿名函数,而这个匿名函数由保持着对elem的引用,进而保持着对n-2次的...因此,这将造成内存泄漏。

解决方案:setInterval中的参数1的代码改为newElem = outer()();

这一节内容的具体剖析,可以见资料1和资料2。

4 Chrome内存分析工具

Chrome(最新的86版本)开发者工具中有两个关于内存的分析工具:

PerformanceJavaScript常见几种的内存泄漏

Memory

JavaScript常见几种的内存泄漏

相关免费学习推荐:javascript(视频)

以上就是JavaScript常见几种的内存泄漏的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2724614.html

(0)
上一篇 2025年3月7日 23:15:34
下一篇 2025年2月24日 05:53:27

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • JavaScript算法之归并排序算法(详解)

    在本文中,我们学习 Merge Sort 背后的逻辑,并用 JavaScript 实现。最后,在空间和时间复杂度方面将归并排序与其他算法进行比较。 归并排序背后的逻辑 归并排序使用分而治之的概念对给定的元素列表进行排序。它将问题分解为较小的…

    2025年3月7日
    100
  • 避免在JS脚本中过多使用 if 语句,6种代替 if 的方法介绍

    推荐教程:《JavaScript视频教程》 最近在重构代码时,我发现早期的代码使用太多的 if 语句,其程度是我从未见过的。这就是为什么我认为分享这些简单的技巧是非常重要的,这些技巧可以帮助我们避免过多的使用 if 语句。 接下来会介绍6种…

    2025年3月7日
    200
  • JavaScript如何禁止刷新页面

    JavaScript禁止刷新页面的方法:1、禁用F5刷新,代码为【if (event.keyCode == 116) 】;2、禁止右键弹出菜单,代码为【document.oncontextmenu = function ()】。 本教程操作…

    2025年3月7日
    200
  • javascript介绍前端安全知多少

    今天javascript栏目介绍前端安全。 前言 Hello,AV8D~今天我们要分享的主题是前端Web安全。web安全的重要性不言而喻,是所有互联网企业都绕不开的话题。 在web前端领域,尽管浏览器已经在系统层面帮我们做了诸多的隔离和保护…

    2025年3月7日 编程技术
    200
  • 详解javascript中逻辑运算符

    推荐教程:《JavaScript视频教程》 逻辑赋值是对现有数学和二进制逻辑运算符的扩展。我们先复习一下,然后看看把它们结合在一起能得到什么。 首先,我们来看下 JS 中条件运算符与无条件运算符之间的区别。 无条件 vs 有条件 数学运算符…

    2025年3月7日
    200
  • 深入了解JavaScript中的null

    推荐教程:《JavaScript视频教程》 JavaScript有2种类型:基本类型(string, booleans number, symbol)和对象。 对象是复杂的数据结构,JS 中最简单的对象是普通对象:一组键和关联值: let …

    2025年3月7日
    200
  • 怎样用 TensorFlow.js 创建基本的 AI 模型?

    在本文中我们来研究怎样用 TensorFlow.js 创建基本的 AI 模型,并使用更复杂的模型实现一些有趣的功能。我只是刚刚开始接触人工智能,尽管不需要深入的人工智能知识,但还是需要搞清楚一些概念才行。 什么是模型? 真实世界是很复杂的,…

    2025年3月7日 编程技术
    200
  • settimeout和setinterval之间有什么区别?

    区别:setTimeout只运行一次,也就是说设定的时间到后就触发运行指定代码,运行完后即结束;而etinterval是一直循环运行下去,即每到设定时间间隔就触发指定代码,要想停止,需要使用clearInterval()函数。 settim…

    2025年3月7日
    200
  • JavaScript输出方式有哪些

    JavaScript输出方式有:1、alert输出,在标签【】添加相关代码;2、【document.write】输出,直接输出在页面当中。 本教程操作环境:windows10系统、javascript1.8.5,本文适用于所有品牌的电脑。 …

    2025年3月7日 编程技术
    200
  • 介绍js的四种类型检测方法及根据jquery写的工具方法

    javascript栏目检测方法及根据jquery写的工具方法。 简介 今天咱们主要研究的是关于js的四种类型检测方法,说到js的类型检测,就不得不提提js的几种数据类型,类型就不详情说明了,毕竟文档上面都一清二楚,我们就只罗列出来: 文档…

    2025年3月7日 编程技术
    200

发表回复

登录后才能评论