创建内存泄漏(js的问题)

如果没有有意识地编写代码来避免内存泄漏,那么内存泄漏几乎是不可避免的JavaScript问题。它们的发生方式有很多种,所以我们只重点介绍几种比较常见的情况。

内存泄漏实例1:对不存在的对象的悬空引用

考虑以下代码:

var theThing = null;
var replaceThing = function () {var priorThing = theThing; var unused = function () {// 'unused'是'priorThing'被引用的唯一地方。// 但'unused'从未被调用过if (priorThing) {console.log("hi");}};theThing = {longStr: new Array(1000000).join('*'),  // 创建一个1MB的对象someMethod: function () {console.log(someMessage);}};
};
setInterval(replaceThing, 1000);    // 每秒钟调用一次 "replaceThing"。

如果你运行上述代码并监测内存使用情况,你会发现你有一个明显的内存泄漏,每秒泄漏整整一兆字节!而即使是手动垃圾收集器(GC)也无济于事。因此,看起来我们每次调用 replaceThing 都会泄漏 longStr。但是为什么呢?

每个theThing对象包含它自己的1MB longStr对象。每一秒钟,当我们调用 replaceThing 时,它都会在 priorThing 中保持对先前 theThing 对象的引用。

但是我们仍然认为这不会是一个问题,因为每次通过,先前引用的priorThing将被取消引用(当priorThing通过priorThing = theThing;被重置时)。而且,只在 replaceThing 的主体和unused的函数中被引用,而事实上,从未被使用。

因此,我们又一次想知道为什么这里会有内存泄漏。

为了理解发生了什么,我们需要更好地理解JavaScript的内部工作。实现闭包的典型方式是,每个函数对象都有一个链接到代表其词法作用域的字典式对象。如果在replaceThing里面定义的两个函数实际上都使用了priorThing,那么它们都得到了相同的对象就很重要,即使priorThing被反复赋值,所以两个函数都共享相同的词法环境。但是一旦一个变量被任何闭包使用,它就会在该作用域内所有闭包共享的词法环境中结束。而这个小小的细微差别正是导致这个可怕的内存泄露的原因。

内存泄漏实例2:循环引用

考虑下面代码:

function addClickHandler(element) {element.click = function onClick(e) {alert("Clicked the " + element.nodeName)}
}

这里,onClick有一个闭包,保持对element的引用(通过element.nodeName)。通过将onClick分配给element.click,循环引用被创建;即: elementonClickelementonClickelement...

有趣的是,即使 element 被从DOM中移除,上面的循环自引用也会阻止 element 和onClick被收集,因此会出现内存泄漏。

避免内存泄漏:要点

JavaScript的内存管理(尤其是垃圾回收)主要是基于对象可达性的概念。

以下对象被认为是可达的,被称为 "根":

  • 从当前调用堆栈的任何地方引用的对象(即当前被调用的函数中的所有局部变量和参数,以及闭包作用域内的所有变量)

  • 所有全局变量

只要对象可以通过引用或引用链从任何一个根部访问,它们就会被保留在内存中。

浏览器中有一个垃圾收集器,它可以清理被无法到达的对象所占用的内存;换句话说,当且仅当GC认为对象无法到达时,才会将其从内存中删除。不幸的是,很容易出现不再使用的 "僵尸 "对象,但GC仍然认为它们是 "可达的"。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/192833.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Redis7--基础篇4(Redis事务)

Redis事务是什么 可以一次执行多个命令,本质是一组命令的集合,一个事务中的所有命令都会序列化,按顺序串行,而不会被其他命令插入。 其作用就是在一个队列中,一次性、顺序、排他的执行一系列命令。 Redis事务 VS 数据…

【每日一题】拼车+【差分数组】

文章目录 Tag题目来源解题思路方法一:差分 写在最后 Tag 【差分数组】【数组】【2023-12-02】 题目来源 1094. 拼车 解题思路 本题朴素的解题思路是统计题目中提到的每一个站点的车上人数,如果某个站点的车上人数大于车上的座位数直接返回 false&…

SSE4.2 指令集内置函数来加速32位循环冗余校验(CRC-32)计算

1、_mm_crc32_u8 为什么比查表快? _mm_crc32_u8 指令使用了 SIMD 技术(即单指令多数据流技术),可以同时处理多个字节的数据。这些字节被打包成 64 位整数,然后使用单条 _mm_crc32_u64 指令计算它们的 CRC-32 校验和。…

基于 Vue、Datav、Echart 框架的 “ 数据大屏项目 “,通过 Vue 组件实现数据动态刷新渲染,内部图表可实现自由替换

最近在研究大数据分析,基于 Vue、Datav、Echart 框架的 " 数据大屏项目 ",通过 Vue 组件实现数据动态刷新渲染,内部图表可实现自由替换。部分图表使用 DataV 自带组件,可进行更改,详情请点击下方 DataV 文档…

flask中遇到ImportError: cannot import name ‘url_encode‘ from ‘werkzeug‘

报错信息 Traceback (most recent call last): File “book_management_sys.py”, line 5, in from forms import Login, SearchBookForm, ChangePasswordForm, EditInfoForm, SearchStudentForm, NewStoreForm, StoreForm, BorrowForm File “C:\pythonProject\pythonProject…

abapgit 安装及使用

abapgit 需求 SA[ BASIS 版本 702 及以上 版本查看路径如下: 安装步骤如下: 1. 下载abapgit 独立版本 程序 链接如下:raw.githubusercontent.com/abapGit/build/main/zabapgit_standalone.prog.abap 2.安装开发版本 2.1 在线安装 前置条…

【C++】类和对象——初始化列表和static修饰成员

首先我们来谈一下初始化列表,它其实是对于我们前边构造函数体内初始化的一种补充,换一种说法,它以后才是我们构造函数的主体部分。 我们先考虑一个问题,就是一个类里面有用引用或const初始化的成员变量,比如说&#xf…

HTML_web扩展标签

1.表格标签 2.增强表头表现 4.表格属性(实际不常用) 结构标签: 合并单元格: 更多请查看主页

从零开始,探索Spring框架的魅力与实践

Spring 1,介绍1.1 为什么要学?1.2 学什么? 2,Spring相关概念2.1 初识Spring2.1.1 Spring家族2.1.2 了解Spring发展史 2.2 Spring系统架构2.2.1 系统架构图2.2.2 spring主要内容 2.3 Spring核心概念2.3.1 目前项目中的问题2.3.2 IOC、IOC容器、Bean、DI…

影刀实例五,网页表单中多下拉框填写问题

一,背景 网页表单中,经常有这样一个场景,填写籍贯.并且是以三个下拉框表示,分别代表省,市,县.并且都是非标准的,不能直接使用影刀内置命令.常规思路是:分别处理省,市&…

万能的视频格式播放器

今天博主给大家带来一款“万能”的视频播放器——VLC Media Player,支持的文件格式非常多,大家快来一起看看吧! VLC Media Player 是一款可播放大多数格式,而无需安装编解码器包的媒体播放器。可以播放 MPEG-1、MPEG-2、MPEG-4、D…

C语言-指针_02

指针-02 1. 指针的指针 概念&#xff1a;指针变量中存储的是指针的地址&#xff0c;又名 二维指针 语法&#xff1a; 数据类型 **p;示例&#xff1a; #include <stdio.h> int main(int argc, char const *argv[]) {int num 10;int *p1 &num;int **p2 &p1…

Java八股文面试全套真题【含答案】-Web前端篇

以下是一些关于JavaScript语言的经典面试题以及它们的答案&#xff1a; JavaScript的数据类型有哪些&#xff1f;它们的特点是什么&#xff1f; 答案&#xff1a;JavaScript的数据类型包括基本数据类型&#xff08;undefined、null、boolean、number、string&#xff09;和引用…

Python Flask 框架开发

1. Python 代码示例&#xff08;使用 Flask 框架&#xff09; 1.1 安装依赖库 pip install flask flask_sqlalchemy flask_login flask_wtf 1.2 主应用文件 app.py from flask import Flask, request, jsonify, redirect, url_for, render_template, flash from flask_sqla…

深度学习——第1章 深度学习的概念及神经网络的工作原理

1.1 序言——探索智能机器 千百年来&#xff0c;人类试图了解智能的机制&#xff0c;并将它复制到思维机器上。 人类从不满足于让机械或电子设备帮助做一些简单的任务&#xff0c;例如使用滑轮吊起沉重的岩石&#xff0c;使用计算器做算术。 人类希望计算机能够自动化执行更…

医美店会员管理系统预约小程序作用是什么

医美在美业中占据着一定地位&#xff0c;爱美使然和经济独立、悦己消费下&#xff0c;不少女性会前往医美机构做脸部整容、嫩肤补水等服务&#xff0c;如美容院一样都是具备本地外地属性的&#xff0c;因此在如今互联网盛行下&#xff0c;商家需要借势线上破解难题及增强生意效…

【预测工具】不须编码的预测和数据可视化工具

有一天&#xff0c;我的同事问我&#xff0c;他应该如何做一个快速预测模型而不是Excel&#xff0c;并产生比线性回归或Excel图中的那些简单方程更好的结果。这是我的答案。 TableCurve 2D (Image by author) Sigmaplot很早以前就推出了这个软件。它已被广泛用于在数据中寻找最…

Structured Streaming: Apache Spark的流处理引擎

欢迎来到我们的技术博客&#xff01;今天&#xff0c;我们要探讨的主题是Apache Spark的一个核心组件——Structured Streaming。作为一个可扩展且容错的流处理引擎&#xff0c;Structured Streaming使得处理实时数据流变得更加高效和简便。 什么是Structured Streaming&#…

【java+vue+微信小程序项目】从零开始搭建——健身房管理平台(2)后端跨域、登录模块、springboot分层架构、IDEA修改快捷键、vue代码风格

项目笔记为项目总结笔记,若有错误欢迎指出哟~ 【项目专栏】 【java+vue+微信小程序项目】从零开始搭建——健身房管理平台(1)spring boot项目搭建、vue项目搭建、微信小程序项目搭建 【java+vue+微信小程序项目】从零开始搭建——健身房管理平台(2)后端跨域、登录模块、sp…

python 图书馆选座小程序源码

开发工具&#xff1a; PyCharm&#xff0c;mysql5.7&#xff0c;微信开发者工具 技术说明&#xff1a; python django html 小程序 功能介绍&#xff1a; 用户端&#xff1a; 登录注册&#xff08;含授权登录&#xff09; 首页显示搜索房间&#xff0c;轮播图&#xff0…