【JavaScript】内存管理和垃圾收集机制

【JavaScript】JavaScript 垃圾回收机制深度解析:内存管理的艺术 在这个信息爆炸的时代,每一行代码都可能成为数字海洋中的璀璨星光,亦或是悄然累积的暗流。JavaScript,作为互联网世界的通用语言,它的每一次呼吸——数据的创建与消亡,都离不开垃圾回收机制的精密调控。在这篇文章中,我们将携手踏上一场深入JavaScript内存管理腹地的探险之旅,揭开垃圾回收机制那既神秘又强大的面纱,让每一次内存的分配与回收,都能成为推动应用高效运转的强劲动力。 阅读详情

师傅给我的模拟面试,感觉我个人对这点没深入吧,再总结学习以下。

简介

像其他的编程语言都有各自底层的内存管理接口,比如 C 语言的 malloc() 和 free()。但是,JavaScript 是在创建变量时自动分配内存,在不使用时自动释放,这个释放过程称为垃圾回收。

JavaScript 的这种自动释放的机制可以让我们开发者在大部分时间都不需要关心 JavaScript 的内存管理,但话是这么说,我们还是要了解一下滴。

内存的生命周期

大部分编程语言,内存的生命周期都大概分为三步:

  1. 分配你所需的内存
  2. 使用分配到的内存(读、写)
  3. 不需要时将其释放

JavaScript 的内存分配

1. 值的初始化

为了不让咋们前端程序员分配内存,JavaScript 在定义变量时就完成了内存分配。

let n = 123; // 给数值变量分配内存
let s = "string"; // 给字符串分配内存

// 给对象及其包含的值分配内存
let o = {
  a: 1,
  b: null,
};

// 给数值及其包含的值分配内存(跟对象差不多)
let arr = [1, null, "string", {}];

// 给函数(可调用的对象)分配内存
function f(a) {
  return a * 2;
}

// 函数表达式(回调函数)也能分配一个对象
setTimeout(function(){
    console.log('callBack fun');
},1000)
2.通过函数调用分配内存

有些函数调用的结果是分配对象内存:

const d = new Date() // 分配一个 Date 对象
const e = document.createElement('div') // 分配一个 DOM 元素对象

有些方法返回的结果分配新变量或者新对象内存:

let s = "string";
let s2 = s.substring(0, 3); // s2 是一个新的字符串
// 因为字符串是不变量
// JavaScript 可能绝对不分配内存
// 只是存储了 [0-3] 的范围

let arr = [1, 2];
let arr2 = [3, 4];
let arr3 = arr.concat(arr2)
// arr 数组有四个元素,是 arr 连接 arr2 的结果

使用值(内存)

使用值的过程实际上是对分配内存进行读取或者写入的操作。读取与写入可能是写入一个变量或者一个对象的属性值,甚至是传递函数的参数。

释放内存

当内存不再需要使用时释放内存,但最难的任务是我们要如何找到“哪些被分配的内存确实是已经不再需要了”,如果没有垃圾回收机制,就需要开发者手动去确定程序中那一块内存不再需要了并且主动去释放它。因此,大部分内存管理的问题都在这个阶段。

大部分高级语言都内嵌了“垃圾回收器”,它的主要工作是跟踪内存的分配和使用,以便当分配的内存不再使用时,自动释放它。但还是存在一些内存是无法通过垃圾回收器进行跟踪,因此,上述跟踪也只是一个近似的过程,而不是百分之百。

垃圾回收算法

因为内存无法达到百分百跟踪,因此,垃圾回收实现只能限制的解决一般问题。我们主要需要了解的就是主要的垃圾回收算法和他们的局限性。

引用的概念

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

在 JavaScript 中,引用“对象”的概念不仅特指 JavaScript 对象,还包括作用域(全局作用域、函数作用域、块级作用域)。

引用计数算法

最初始的垃圾收集算法,算法很简单,就是把“对象是否不再需要”简化定义为“对象有没有其他对象引用到它”。如果没有引用指向该对象,对象就会被垃圾收集机制回收。

事例:

let o = {
  a: {
    b: 2,
  },
};
// 两个对象被创建,一个作为另一个的属性被引用,另一个被分配给变量 o
// 很显然,没有一个可以被垃圾收集

let o2 = o; // o2 变量是第二个对“这个对象”的引用

o = 1; // 现在,“这个对象”只有一个 o2 变量的引用了,“这个对象”的原始引用 o 已经没有

let oa = o2.a // 引用“这个对象”的 a 属性;现在,“这个对象”有两个引用了,一个是 o2,一个是 oa

o2 = 'my_new_o2' // 虽然最初的对象现在已经是零引用了,可以被垃圾回收了; 但是它的属性 a 的对象还在被 oa 引用,所以还不能回收

oa = null // a 属性的那个对象现在也是零引用了; 它可以被垃圾回收了

但是引用计数存在一个很严重的问题,那就是循环引用。循环引用的情况对象无法被垃圾回收机制回收。比如下面的例子,两个对象被创建,并相互引用,形成了一个循环。他们被调用之后会离开函数作用域,所以他们应该已经没有用到了,理论上应该被回收了。但是,引用计数算法考虑到它们互相之间至少有一次引用,所以他们不会被回收。

function f() {
  let o = {};
  let o2 = {};
  o.a = o2; // o 引用 o2
  o2.a = o; // o2 引用 o
  return "success";
}
f();

正是因为上面的限制,早期 IE 浏览器用引用计数的方式对 DOM 对象进行垃圾回收时,经常造成对象被循环引用从而造成内存泄漏问题。

let div;
window.onload = function () {
  div = document.getElementById("myDivElement");
  div.circularReference = div; // 这里循环引用了
  div.lotsOfData = new Array(10000).join("*");
};

标记清除算法

这个算法把“对象是否不再需要”简化定义为“对象是否可以获得”。

这个算法会假定设置一个叫做根(root)的对象(在 JavaScript 中,根是全局对象 Global)。垃圾回收器将定期聪根开始,找所有从根开始引用的对象,然后找到这些对象引用的对象...以此类推,从根开始,垃圾回收器将找到所有可以获得到的对象和收集所有不能获得的对象。

image

这个算法比引用计数算法较好,因为在引用计数中,“有零引用的对象”总是不可获取的,但是相反却不一定,参考循环引用;而标记清除因为必须要获得,相互引用的两个对象是无法通过第三方引用获得的。

从 2012 年起,所有现代浏览器都使用了标记清除垃圾回收算法。所有对 JavaScript 垃圾回收算法的改进都是基于标记清除算法的改进,并没有改进标记清除算法本身和它对“对象是否不再需要”的简化定义。

深入我们可以了解下 V8 对 GC 的优化。

V8 对 GC 的优化

待更新...

参考文献

内存管理 - JavaScript | MDNjs垃圾回收机制

JvavaScript编程语言-垃圾回收,分代收集,增量收集,闲时收集,可达性 对于开发者来说,JavaScript 的内存管理是自动的、无形的。我们创建的原始值、对象、函数……这一切都会占用内存。当我们不再需要某个东西时会发生什么?JavaScript 引擎如何发现它并清理它。 阅读详情

相关推荐

自制土壤温湿度检测计:从传感器选型到单片机实现全解析

在嵌入式开发中,传感器数据采集与处理是连接物理世界与数字逻辑的桥梁。土壤湿度检测作为智慧农业和园艺智能化的基础应用,其核心原理是利用土壤含水量变化引起介电常数或电阻率改变,通过传感器转换为电信号,再由单片机内置ADC进行模数转换和数值标定。这一过程涉及信号调理、滤波算法和显示交互等关键环节,是理解ADC采样、传感器驱动和嵌入式系统设计的绝佳实践。从简单的51单片机课程设计到基于STM32的物联网节点,此类检测装置可广泛应用于花盆浇水提醒、农田墒情监测及自动化灌溉系统。本文以自制土壤温湿度检测计为例,详细拆解

weixin_33979203的博客 464

js 第四章总结 (变量、作用域和内存问题)

一、基本类型和引用类型的值 1.变量的数据类型的值: (1)基本类型值:Undefined、Null、Boolean、Number、String; 不可添加属性 (2)引用类型值:可以添加属性和方法 如: var person = new Object(); //添加一个名为name的属性 person.name = "linlin"; alert(person.name); //linlin...

ladream的博客 200

手把手教你用IN-Sight智能相机实现双向TCP/IP通讯(附网络调试助手推荐)

本文详细解析了IN-Sight智能相机实现双向TCP/IP通讯的完整流程。通过将相机同时配置为TCP服务器和客户端,构建了与上位机(如PLC、MES)稳定可靠的数据交换通道。文章深入剖析了发送(TCPDevice)与接收(ReadDevice)通道的独立配置、关键参数设置(如结束符CR+LF)、高效调试工具选择以及实战避坑指南,帮助工程师快速掌握这一构建柔性产线数据节点的核心技术。

qsc9012345的博客 670

第4章 变量、作用域和内存---JS红宝书书摘系列笔记

一、基本类型和引用类型 ECMAScipt变量可能分为两种数据类型:基本类型和引用类型。 基本类型:指简单的数据段;包括Undefined、Null、Bo...

nqxcwl的专栏 118

利用 Openocd 和 FT2232H 实现 ARMv8(Coretex-A53)高效调试方案

本文详细介绍了如何利用开源工具OpenOCD与高性能USB转接芯片FT2232H,构建一套针对ARMv8架构(如Cortex-A53)的高效、低成本调试方案。内容涵盖从环境搭建、驱动配置、核心调试架构解析到实战问题排查的全过程,帮助开发者实现对多核处理器的透明、可控调试,是嵌入式Linux及底层开发的实用指南。

weixin_29163581的博客 280

STM32 热敏电阻测量温度

1、硬件 STM32F103C8T6、热敏电阻传感器、OLED。 2、热敏电阻传感器的介绍

weixin_54721788的博客 1万+

JS变量与作用域-2

1.作用域 变量起作用的区域或范围:变量的生命周期和能访问到变量的区域 全局作用域:函数体外部,函数内也可以访问,当所有的程序执行完毕才释放(全局变量会污染,尽量少写) 局部作用域:函数作用域,只能在函数体内部访问,函数执行完毕就释放 JS中没有块级作用域{…} function fn(){ var x = y = 1; } fn(); console.log(y); console.log(x); 结果为1 报错,在函数内部不用var声明的是全局变量,y可以输出 var name = 'xm'; fu

weixin_46143669的博客 153

使用C++实现DNS欺骗攻击

其中,domain_name表示需要欺骗的域名,dns_server_ip表示实际DNS服务器的IP地址,fake_ip表示需要重定向到的IP地址。在DNS查询过程中,当客户端向DNS服务器请求解析某个域名时,DNS服务器会返回该域名对应的IP地址。DNS劫持是一种常见的网络攻击方式,通过篡改DNS响应数据,使得用户访问的网站被重定向到攻击者指定的恶意站点。我们使用C++编写一个简单的DNS欺骗程序,使得当客户端请求解析特定的域名时,我们可以将其重定向到指定的IP地址。使用C++实现DNS欺骗攻击。

TechGlide的博客 411

JS变量、作用域

变量   可以理解成一个存放数据的容器,方便多次使用这个值   在命名的时候注意:   1.区分大小写   2.不用关键字和保留字   3.命名有意义(不用拼音和带数字序号的名称,可以用下划线/驼峰来命名,实际开发中...

weixin_30511107的博客 69

Unity中实现俄罗斯方块

二:实现思路 ——创建每一个方块可移动到的位置点,可以理解为创建一个游戏地图,从(0,0)点开始依次向x轴和y轴延伸,例如x最大为9,y最大为19,则创建了一个20行10列的地图 ——制作每一个形状的预制体,Shape是每一个整体形状,Block是每一块小方块,CenterPos代表这个形状的旋转中心 ——创建GameController脚本控制游戏逻辑,挂载到面板物体上。创建Block脚本控制每个形状的操作,挂载到每个形状上 ——在GameController脚本中编...

L的博客 8557

KEPServerEX物联网网关(IoT Gateway)REST客户端代理(非原创)

(中文版)资料来源于【OPC-KEPServerEX学习KEPWare交流】905485143群的【455196383】【零下一度】 一。KEPServerEX物联网网关REST客户端代理演示 在KSE中,首先构建一个带有通道/设备/标签的模拟器系统。 例如,下面是三个随机项目。 直接到IoT网关插件,添加新代理。 从类型列表中选择REST Client。 终结点...

-雲飛兄-博客 5805

JS | 深入谈谈 JavaScript 的垃圾回收机制

垃圾回收机制也称Garbage Collection简称GC。在JavaScript中拥有自动的垃圾回收机制,通过一些回收算法,找出不再使用引用的变量或属性,由JS引擎按照固定时间间隔周期性的释放其所占的内存空间。在C/C++中需要程序员手动完成垃圾回收。

青春木鱼的博客 2201

RK3588平台开发系列讲解(硬件篇-功能外设2)

RK3588 芯片内置两个USB3.0 OTG控制器(内嵌2个USB2.0 OTG,下图绿色处),1个USB3.0 HOST 控制器,2个USB2.0 HOST控制器。这些控制器与PHY的内部复用图如下:USB3.0 OTG0 控制器支持SS/HS/FS/LS, 内嵌的USB2.0(HS/FS/LS)信号采用USB2.0 OTG PHY, 信号名见下图的红色方框内;RK3588目前仅此接口支持做Fireware的Download,应用中请务必要预留出。

whm128的博客 2508

js高级程序设计(第三版)这一遍的总结——第四章变量、作用域和内存问题

一、基本类型和引用类型 1、基本类型的复制 基本类型复制之前和复制之后的两个值是完全独立的,并不会相互影响。 2、引用类型的复制 引用变量在复制的时候复制的是变量的指针,复制操作结束后,两个变量实际上将引用同一个对象。 3、参数传递 ECMAScript 中所有函数的参数都是按值传递的。也就是说,把函数外部的值复制给函数内部的参数,就和把值从一个变量复制到另一个变量一样

kellywong的博客 307

Qt5.15.2配置安卓环境

否则,将会跳转到github,你可以自行下载解压到你设置的目录中,然后Qt会自动检测到。以上所需的工具确实有些繁多,而且如果单独下载又涉及科学上网问题,版本问题十分麻烦,好在Qt Creator 4.12之后已经可以自动下载SDK工具,NDK,基础包,openssl,以及gradle等,十分省心。回到正题,无论通过在线安装的方式,安装时勾选了Android,还是编译的方式,编译时编译了Qt Android库,想要使用Qt开发安卓应用仍然需要一些其他工作,包括安装编译安卓项目需要的SDK,NDK等。

weixin_41392061的博客 978

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

一文看懂JS的垃圾收集系统

前言 关于JS的垃圾收集系统,我们很多人可能知道他是具有自动收集的机制,但是可能并没有深入了解,或者怀疑了解这玩意到底有什么好处。 自动垃圾收集 自动垃圾收集指的是执行环境会负责管理代码执行过程中所使用的内存,在C中手动跟踪内存使用是开发人员的一项基本任务,JS虽说实现了自动内存管理,但是并不意味着这种管理机制很复杂,相反其实很简单,JS中的垃圾收集器会按照固定的时间间隔取搜寻那些不在使用的变量...

eswang的优快云博客 385

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

JavaScript的垃圾回收机制

目录 一、什么是js的垃圾回收机制 二、为什么需要垃圾回收机制 三、垃圾回收机制的方法及流程 1、JS中最常见的垃圾回收方式是标记清除 2、还有一种方式是引用计数 一、什么是js的垃圾回收机制 1、垃圾回收机制主要是由垃圾收集器(garbage collector,简称GC)的后台进行监控、清理对象,并及时回收空闲内存,并且会按照固定的时间间隔周期性的执行。 2、垃圾收集器最主要的是监控数据的可达性 所谓的可达性就是以某种方式可以访问或者可调用的值,它们因为可达性而不被清理。 (1)有.

Han_Zhou_Z的博客 1645

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

JS的内存空间

JS基础

hong 1094

《JavaScript高级程序设计(第三版)》读书笔记01 变量、作用域和内存问题

第4章 变量、作用域和内存问题 4.1 基本类型和引用类型的值 基本类型: 有undefined,null,boolean,number,string. 值在内存中占据固定大小的空间,因此被保存在栈内存中。 从一个变量向另一个变量赋值基本类型的值,会创建这个值的一个副本。 确定值的基本类型使用typeof操作符。 引用类型: 值是对象,保存在堆内存中。 包含值的变量包含的不是对象本身,是指...

DurianPudding的博客 211

变量二

变量保存数据的容器; 数据分为基本类型(不修改,不能添加属性,它们的方法和属性都在Number,String等中,数据存储在栈) 所有的字符串方法都是返回一个新的字符串而不是修改本来的(不修改)。基本类型复制副本改变不影响原来的,基本类型传参就是传值 引用类型(可修改,地址存在栈中,数据存储在堆中),即使内容一样地址也就是堆中的位置不一样也不相等;引用类型复制副本改变影响原来的,因为两个指向...

weixin_42587425的博客 301

Javascript-8-垃圾收集

Javascript具有自动垃圾收集机制,也就是说,执行环境会负责管理代码执行过程中使用的内存。这种垃圾收集机制的原理其实很简单:找出那些不再继续使用的变量,然后释放其占用的内存。为此,垃圾收集器会按照固定的时间间隔(或代码执行中预定的收集时间),周期性地执行这一操作。 1,标记清除 Javascript中最常用的垃圾收集方式是标记清除。当变量进入环境时,就将这个变量标记为“进入环境”。从逻辑上...

吃太多会胖哦的博客 161

【javascript高级程序设计】读书摘录1 JavaScript简介

一直在做服务器端的开发,却迫不得已要做一些前端页面的开发。努力恶补js中,顺便熟悉下node.js。 目标:前后端兼修。么么哒。 第一章、Javascript简介 1.      ECMAScript与javascript的关系 2.      DOM级别 DOM0实际上是不存在的标准,指IE4和NetScape4最初支持的DHTML DOM1主要是映射文档的结构 DOM2扩

专注、专心 1197

深入探讨JavaScript的垃圾回收机制

垃圾回收器负责跟踪哪些对象是不再需要的,并释放它们所占用的内存,以防止内存泄漏和不必要的内存占用。然而,引用计数的主要缺点是它无法处理循环引用的情况。为了解决这个问题,一些现代的JavaScript引擎引入了更复杂的垃圾回收策略,如弱引用、循环引用检测等。这种方法的优点是它可以有效地处理循环引用的情况,因为只要对象从根可达,它们就会被标记为活动,无论它们之间是否存在循环引用。引用计数是一种更直观的垃圾回收策略,但它在现代JavaScript引擎中并不常用,主要是因为它无法处理循环引用的情况。

qq_43536788的博客 427

js垃圾回收机制

一、垃圾收集 * 什么是垃圾: * 一般来说,没有被引用的对象就是垃圾,就要被清除。 * 有个例外,如果几个对象引用形成一个环,它们互相引用,但是根访问不到它们,这几个对象也是垃圾,也要被清除。 * 垃圾回收GC的全拼是 Garbage Collection 其在维基百科的定义是:在计算机科学中,垃圾回收是一种自动的内存管理机制。当一个电脑上的动态内存不再需要时,就应该予以释放,以让出内存,这种内存资源管理,称为垃圾回收 * JavaScript具有自动垃圾收集机制,也就是说,执行环境会

夏天的博客 341

浅谈javascript垃圾收集机制

因为已经研二了,眼看就要找工作了,心中很忐忑。好怕面试官当众吊打我,真的好怕好怕……所以想着开个博客,整理分享一些js的基础知识,充实自己的同时,也能分享给需要的人。今天想要分享的小知识,是关于javascript的垃圾收集机制(GC(Garbage Collection) )。 自动垃圾收集机制不同于C/C++需要编程人员手动跟踪内存的使用情况,javascript拥有一套自动垃圾收集机制,也就

完美A型血的博客 463

JavaScript内存管理

不管什么样的编程语言,在代码的执行过程中都是需要给它分配内存的,有些编程语言需要手动管理内存,某些编程语言可以自动帮助我们管理内存。内存管理的生命周期我们创建的原始值、对象、函数都会占用内存,但是JavaScript不需要手动进行管理,JavaScript引擎会帮助我们处理好。JavaScript会在定义数据时为我们分配内存 内存的大小是有限的,当内存不再需要的时候,我们需要对其进行释放。现代的编程语言都是有自己的垃圾回收机制:GC算法有几种实现方案:...

m0_51636525的博客 470
上一篇: 【JavaScript】手写深拷贝 2.0(更新 2022-07-15)
下一篇: 【HTML】响应式邮箱(HTML Email)编写 mjml
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值