当前位置: 首页 > news >正文

JavaScript 内存管理

1. 内存分配

当 JavaScript 执行代码时,会自动分配内存来存储变量、对象、函数等。内存分配主要包括以下几种情况:

变量声明:声明变量时,JavaScript 会为其分配内存。

let x = 10; // 分配内存存储数字 10

对象创建:创建对象时,JavaScript 会为其分配内存。

let obj = { a: 1, b: 2 }; // 分配内存存储对象

数组创建:创建数组时,JavaScript 会为其分配内存。

let arr = [1, 2, 3]; // 分配内存存储数组

函数声明:声明函数时,JavaScript 会为其分配内存。

function add(a, b) {return a + b;
} // 分配内存存储函数

2. 内存使用

在 JavaScript 中,内存使用主要涉及变量的赋值、对象属性的访问和修改等操作。

变量赋值:将值赋给变量时,会在内存中更新该变量的值。

x = 20; // 更新内存中 x 的值

对象属性访问和修改:访问和修改对象属性时,会在内存中查找和更新相应的属性。

obj.a = 3; // 更新内存中 obj.a 的值

3. 垃圾回收

JavaScript 通过垃圾回收机制自动释放不再使用的内存。垃圾回收的主要策略包括标记-清除(Mark and Sweep)、引用计数(Reference Counting)等。

标记-清除(Mark and Sweep)
这是最常用的垃圾回收算法。

标记:从根节点(通常是全局对象和当前执行的函数)开始,递归地遍历所有可达对象,并标记这些对象。
清除:清除所有未被标记的对象,释放它们占用的内存。

引用计数(Reference Counting)
虽然现代 JavaScript 引擎不常用此方法,但了解其原理有助于理解内存管理。

引用计数:每个对象都有一个引用计数器,每当有一个地方引用该对象时,计数器加一;当引用被移除时,计数器减一。
释放内存:当引用计数器为零时,对象被视为垃圾,可以被回收。

4. 内存泄漏

内存泄漏是指程序在申请内存后,未能释放已分配的内存,导致内存使用量不断增加。常见的内存泄漏原因包括:

未解除事件监听器:忘记移除事件监听器,导致对象无法被垃圾回收。

document.addEventListener('click', function handler() {// 处理点击事件
});
// 忘记移除事件监听器

闭包:闭包可能导致外部变量被长时间引用,从而无法被垃圾回收。

function createClosure() {const largeArray = new Array(1000000).fill(0);return function() {console.log(largeArray.length);};
}
const closure = createClosure();
// largeArray 一直被 closure 引用,无法被垃圾回收

周期性引用:两个对象互相引用,形成周期性引用,导致垃圾回收器无法识别这些对象为垃圾。

const obj1 = {};
const obj2 = {};
obj1.ref = obj2;
obj2.ref = obj1;
// obj1 和 obj2 形成周期性引用

5. 优化建议

及时解除事件监听器:在不再需要事件监听器时,及时移除。

function addClickListener() {const handler = () => {// 处理点击事件};document.addEventListener('click', handler);// 在适当的时候移除事件监听器document.removeEventListener('click', handler);
}

避免不必要的闭包:尽量减少闭包的使用,避免长时间引用外部变量。

function createClosure() {const largeArray = new Array(1000000).fill(0);const length = largeArray.length;return function() {console.log(length);};
}
const closure = createClosure();
// 只引用 length,而不是整个 largeArray

使用弱引用:在某些情况下,可以使用 WeakMap 和 WeakSet 来存储对象,这些对象不会阻止垃圾回收。

const weakMap = new WeakMap();
const obj = {};
weakMap.set(obj, 'value');
// obj 可以被垃圾回收

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 1.4 边界值分析法
  • ECharts的特点
  • Python中set的用法详解
  • 【2024W32】肖恩技术周刊(第 10 期):太阳神鸟
  • HT8693 10W防破音单声道D类音频功放 9W单声道AB类音频功放
  • Maven配置及使用
  • C++ STL容器(三) —— 迭代器底层剖析
  • 解密谷歌Imagen:AI图像生成的新巅峰
  • 基于vue框架的传统文化传播网站设计与实现f7r43(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。
  • 手语手势识别系统源码分享
  • 应急响应--来不来得及走流程...
  • Unity中,如果你想让多个数字人轮流显示和隐藏
  • 【alist】宝塔面板docker里的alist默认admin无法登录
  • C++速通LeetCode中等第10题-轮转数组(四种方法)
  • 学生党头戴式耳机哪个品牌音质好?四款音质卓越性价比极高推荐
  • 【108天】Java——《Head First Java》笔记(第1-4章)
  • echarts的各种常用效果展示
  • Facebook AccountKit 接入的坑点
  • Java知识点总结(JavaIO-打印流)
  • MD5加密原理解析及OC版原理实现
  • MySQL-事务管理(基础)
  • PHP 的 SAPI 是个什么东西
  • Terraform入门 - 3. 变更基础设施
  • vue.js框架原理浅析
  • XForms - 更强大的Form
  • 分布式任务队列Celery
  • 高度不固定时垂直居中
  • 浅谈Golang中select的用法
  • 实战|智能家居行业移动应用性能分析
  • 试着探索高并发下的系统架构面貌
  • ​Linux·i2c驱动架构​
  • #define,static,const,三种常量的区别
  • (C语言)求出1,2,5三个数不同个数组合为100的组合个数
  • (第二周)效能测试
  • (二)springcloud实战之config配置中心
  • (没学懂,待填坑)【动态规划】数位动态规划
  • (四)stm32之通信协议
  • (转)原始图像数据和PDF中的图像数据
  • .net core MVC 通过 Filters 过滤器拦截请求及响应内容
  • .NET 项目中发送电子邮件异步处理和错误机制的解决方案
  • .net 怎么循环得到数组里的值_关于js数组
  • .net 桌面开发 运行一阵子就自动关闭_聊城旋转门家用价格大约是多少,全自动旋转门,期待合作...
  • .net安装_还在用第三方安装.NET?Win10自带.NET3.5安装
  • .NET成年了,然后呢?
  • .NET应用UI框架DevExpress XAF v24.1 - 可用性进一步增强
  • [].shift.call( arguments ) 和 [].slice.call( arguments )
  • [C/C++入门][字符与ASCII码]6、用代码来转换字符与它的ASCII码
  • [C++ 从入门到精通] 12.重载运算符、赋值运算符重载、析构函数
  • [C++]priority_queue的介绍及模拟实现
  • [c++刷题]贪心算法.N01
  • [CC2642r1] ble5 stacks 蓝牙协议栈 介绍和理解
  • [Debugger]调试Arm设备
  • [emacs] CUA的矩形块操作很给力啊
  • [Git 1]基本操作与协同开发
  • [Java] 什么是IoC?什么是DI?它们的区别是什么?