重学JavaScript高阶知识点(三)—— 详解Js中的内存管理

news2024/10/6 14:23:58

在这里插入图片描述

详解Js中的内存管理

    • 1. 简介
    • 2. 内存生命周期
    • 3. JavaScript 的内存分配
    • 4. 垃圾回收

1. 简介

  • 很多底层语言一般都有底层的内存管理接口,比如 C语言,可以调用对应的API去创建和释放内存空间。
  • 意思是需要手动去创建和释放内存空间,很明显,这不够高级~
  • JavaScript 是在创建变量(对象,字符串等)时自动进行了分配内存,并且在不使用它们时“自动”释放。这个过程叫做**内存回收。**嘿!所以这很高级,但是高级会产生混乱。
    在这里插入图片描述
  • 这意味着,程序可能在我们需要用的时候就已经回收了变量,导致访问不到某个变量,所以就出现了闭包(用于延长变量的生命周期)

2. 内存生命周期

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

  1. 分配你所需要的内存。
  2. 使用分配到的内存(读、写)。
  3. 不需要时将其释放 \ 归还。
  • 所有语言第二步都是明确的。第一和第三步在底层语言中是明确的,但在像 JavaScript 这些高级语言中,大部分都是隐含的,所以我们更要去了解。

3. JavaScript 的内存分配

3.1 值的初始化

  • JavaScript 在定义变量时就完成了内存分配:
// 给数值变量分配内存
let num = 123; 
// 给字符串分配内存
let str = "123"; 
// 给对象及其包含的值分配内存
let obj = {
  a: 1,
  b: null,
}; 
// 给数组及其包含的值分配内存(就像对象一样)
let arr = [1, 'str'];
// 给函数(可调用的对象)分配内存
function fn(a) {
  return a + 2;
} 

3.2 通过函数调用分配内存

  • 函数调用结果是分配对象内存:
// 分配一个 Date 对象
let d = new Date(); 
// 分配一个 DOM 元素
let e = document.createElement("div"); 
  • 有些方法分配新变量或者新对象:
let str = "123";
let str2 = str .substr(0, 1); // str2 是一个新的字符串

在这里插入图片描述

3.3 使用值

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

3.4 当内存不再需要使用时释放

  • 大多数内存管理的问题都在这个阶段。在这里最艰难的任务是找到“哪些被分配的内存确实已经不再需要了”。
  • 它往往要求开发人员来确定在程序中哪一块内存不再需要并且释放它。

4. 垃圾回收

  • 如上所述:自动寻找是否一些内存“不再需要”的问题是无法判定的。因此,垃圾回收实现只能有限制的解决一般问题

4.1 引用计数垃圾收集

  • 垃圾回收算法主要依赖于引用的概念。在内存管理的环境中,一个对象如果有访问另一个对象的权限(隐式或者显式),叫做一个对象引用另一个对象。
  • 在这里,“对象”的概念不仅特指 JavaScript 对象,还包括函数作用域(或者全局词法作用域)。
  • 具体我们可以看下面这个例子:
// 两个对象被创建,一个作为另一个的属性被引用,另一个被分配给变量 obj
// 很显然,没有一个可以被垃圾收集
let obj = {
  a: {
    b: 123,
  },
};

// obj2 变量是对obj的引用
let obj2 = obj; 

// 现在,obj 只有一个 obj2 变量的引用了, obj2 的原始引用obj已经没有了
obj = 123; 

// 这里引用的 a 属性是obj2的了
let oa = obj2.a; 

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

// a 属性的那个对象现在也是零引用了,所以obj可以被回收了
oa = null;
  • 需要注意的是:循环引用会出问题。
  • 该算法有个限制:无法处理循环引用的事例。
function f() {
  let o = {};
  let o2 = {};
  o.a = o2; // o 引用 o2
  o2.a = o; // o2 引用 o
  return "123";
}
f();
  • 在上面的例子中,两个对象被创建,并互相引用,形成了一个循环。
  • 它们被调用之后会离开函数作用域,所以它们已经没有用了,可以被回收了。
  • 然而,引用计数算法考虑到它们互相都有至少一次引用,所以它们不会被回收。
  • 我们再来看一个示例:
let div;
window.onload = function () {
  div = document.getElementById("myDiv");
  div.cur = div;
  div.data= new Array(10000).join("*");
};
  • myDiv 这个 DOM 元素里的 cur 属性引用了 myDiv,造成了循环引用。
  • 如果该属性没有显示移除或者设为 null,引用计数式垃圾收集器将总是且至少有一个引用,所以引用计数法是无法释放的,会造成内存泄漏。
    在这里插入图片描述

4.2 标记 - 清除算法

  • 这个算法把“对象是否不再需要”简化定义为“对象是否可以获得”。
  • 假定设置一个叫做根(root)的对象(在 Javascript 里,根是全局对象)。
  • 垃圾回收器将定期从根开始,找所有从根开始引用的对象,然后找这些对象引用的对象,从根开始,垃圾回收器将找到所有可以获得的对象和收集所有不能获得的对象。
  • 这个算法比前一个要好,因为“有零引用的对象”总是不可获得的,但是相反却不一定
  • 在上面的示例中,函数调用返回之后,两个对象从全局对象出发无法获取。因此,他们将会被垃圾回收器回收。第二个示例同样,一旦 div 和其事件处理无法从根获取到,他们将会被垃圾回收器回收。
  • 当然,它也有限制:无法从根对象查询到的对象都将被清除。尽管这是一个限制,但实践中我们很少会碰到类似的情况,所以无需太过担心。

1. 希望本文能对大家有所帮助,如有错误,敬请指出
2. 原创不易,还请各位客官动动发财的小手支持一波(关注、评论、点赞、收藏)
3. 拜谢各位!后续将继续奉献优质好文
4. 如果存在疑问,可以私信我(文底有V)

在这里插入图片描述

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

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

相关文章

TCP服务器实现将客服端发送的信息广播发送(使用内核链表管理客户端信息)

目录 1.服务器端实现思路 2.服务器端代码 3.客户端代码 4.内核链表代码 5.运行格式 一、服务器端 二、客户端 6.效果 1.服务器端实现思路 Tcp广播服务初始化 等待客户端连接 广播发送 2.服务器端代码 #include "list.h" #include <signal.h> #def…

如何解决IntelliJ IDEA中pom.xml依赖项引发的安全漏洞黄线警告问题

背景 在开发过程中&#xff0c;当我们在pom.xml文件中添加依赖项时&#xff0c;经常会发现IntelliJ IDEA报出黄色警告线条&#xff0c;提示存在潜在的安全漏洞。警告的具体展现形式如下&#xff1a; 解决方案 首先&#xff0c;打开设置菜单界面&#xff0c;接着选择编辑器选…

神经网络复习--神经网络算法模型及BP算法

文章目录 神经网络模型的构成BP神经网络 神经网络模型的构成 三种表示方式&#xff1a; 神经网络的三要素&#xff1a; 具有突触或连接&#xff0c;用权重表示神经元的连接强度具有时空整合功能的输入信号累加器激励函数用于限制神经网络的输出 感知神经网络 BP神经网络 …

[嵌入式系统-75]:RT-Thread-快速上手:正点原子探索者 STM32F407示例

目录 正点原子探索者 STM32F407 上手指南 1. 简介 2. 准备工作 3. 运行第一个示例程序 3.1 编译下载 3.2 运行 继续学习 正点原子探索者 STM32F407 上手指南 1. 简介 探索者 STM32F407 是正点原子推出的一款基于 ARM Cortex-M4 内核的开发板&#xff0c;最高主频为 16…

机器人学导论实验2-差速驱动机器人的运动学与控制BJTU

目录 机器人导论实验-差速驱动机器人的运动学与控制 1 实验目的 2 任务一&#xff1a;前馈控制 2.1 内容分析 2.2 过程分析 2.3 结果分析 3 任务二&#xff1a;闭环控制 3.2 过程分析 3.3 结果分析 4 任务三&#xff1a;闭环控制&#xff08;改进&#xff09; 4.1 内容分…

Kotlin: ‘return‘ is not allowed here

报错&#xff1a;以下函数的内部函数return语句报错 Kotlin: return is not allowed here fun testReturn(summary: (String) -> String): String {var msg summary("summary收到参数")println("test内部调用参数&#xff1a;>结果是 &#xff1a;${msg…

(四十)第 6 章 树和二叉树(树的双亲表存储)

1. 背景说明 2. 示例代码 1) errorRecord.h // 记录错误宏定义头文件#ifndef ERROR_RECORD_H #define ERROR_RECORD_H#include <stdio.h> #include <string.h> #include <stdint.h>// 从文件路径中提取文件名 #define FILE_NAME(X) strrchr(X, \\) ? strrch…

项目管理-计算题公式-补充【复习】

1.EMV决策树 定义&#xff1a;用决策树在若干备选行动方案中选择一个最佳方案。在决策树 中&#xff0c;用不同的分支代表不同的决策或事件&#xff0c;即项目的备选路径。每个决策或事件 都有相关的成本和单个项目风险(包括威胁和机会)。决策树分支的终点表示沿特 定路径发展的…

C++ | Leetcode C++题解之第86题分隔链表

题目&#xff1a; 题解&#xff1a; class Solution { public:ListNode* partition(ListNode* head, int x) {ListNode* small new ListNode(0);ListNode* smallHead small;ListNode* large new ListNode(0);ListNode* largeHead large;while (head ! nullptr) {if (head-…

C语言实现猜数字小游戏

1.随机数生成 要想实现猜数字小游戏&#xff0c;依赖于随机数的生成 1.1 rand()函数 这个函数是用来生成随机数的&#xff0c;返回值是正整数&#xff0c;他的值的范围是0到rand_max之间的&#xff0c;rand_max的值在大多数编译器上面是32767&#xff0c;rand()函数的使用必…

高校课程评价|基于SSM+vue的高校课程评价系统的设计与实现(源码+数据库+文档)

高校课程评价系统 目录 基于SSM&#xff0b;vue的高校课程评价系统的设计与实现 一、前言 二、系统设计 三、系统功能设计 1管理员功能模块 2学生功能 3教师功能 4专家功能 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&…

Node.js基础:从入门到实战

初识 Node.js 与内置模块 &#xff08;初识&#xff09; 1、知道什么是node.js 2、知道node.js可以做什么 3、node.js 中js的组成部分 &#xff08;内置模块&#xff09; 4、用 fs 模块读写操作文件 5、使用 path 模块处理路径 6、使用http 模块写一个基本的web服务器 初识 N…

高精度原理介绍及代码实现

目录 高精度 引入 使用场景 实现原理 高精度加法 数据存储 加法实现 总代码 高精度减法 与加法的不同点&#xff1a; 总代码 高精度乘法 总代码 高精度除法 总结 总注意点 减法注意点 高精度 引入 所谓高精度并不是很高级难懂的东西&#xff0c;只是对传统的…

改进YOLOv5,YOLOv5+CBAM注意力机制

目录 1. 目标检测模型 2. YOLOv5s 3. YOLOv5s融合注意力机制 4. 修改yolov5.yaml文件 5. ChannelAttentionModule.py 6. 修改yolo.py 1. 目标检测模型 目标检测算法现在已经在实际中广泛应用&#xff0c;其目的是找出图像中感兴趣的对象&#xff0c;并确定对象的类别和位…

一文读懂设计模式-单例模式

单例模式&#xff08;Singleton Pattern&#xff09;提供了一种创建对象的最佳方式 单例模式涉及到一个单一的类&#xff0c;该类负责创建自己的对象&#xff0c;同时确保只有单个对象被创建&#xff0c;这个类提供了一种访问其唯一的对象的方式&#xff0c;可以直接访问&…

Redis—图文详解高可用原因

本文不会讲解Redis的用途&#xff0c;关于用途会发另一片文章讲解&#xff0c;本文主要讲的是高可用的原理。 Redis高可用主要有以下三个原因&#xff1a;主从模式(上一篇讲Kafka的文章里有涉及到)&#xff0c;哨兵模式&#xff0c;Redis-Cluster(Redis集群)。 什么是主从模式…

mysql集群NDBcluster引擎在写入数据时报错 (1114, “The table ‘ads‘ is full“)

问题描述&#xff1a;mysql集群在写入数据时&#xff0c;出现上述报错 问题原因&#xff1a;表数据已满&#xff0c;一般是在集群的管理节点设置里面datamemory的值太小&#xff0c;当数据量超过该值时就会出现该问题 解决方案&#xff1a; 修改集群管理节点的config.ini里面…

【Linux 网络】网络编程套接字 -- 详解

⚪ 预备知识 1、理解源 IP 地址和目的 IP 地址 举例理解&#xff1a;&#xff08;唐僧西天取经&#xff09; 在 IP 数据包头部中 有两个 IP 地址&#xff0c; 分别叫做源 IP 地址 和目的 IP 地址。 如果我们的台式机或者笔记本没有 IP 地址就无法上网&#xff0c;而因为…

操作系统原理与实验——实验十四多道批处理作业调度算法应用二

样例 样例一&#xff1a; 1 100 0 5 JOB1 10:06 42分钟 55K JOB2 10:20 30分钟 40K JOB3 10:30 24分钟 35K JOB4 10:36 15分钟 25K JOB5 10:42 12分钟 20K 2 100 0 5 JOB1 10:06 42分钟 55K JOB2 10:20 30分钟 40K JOB3 10:30 24分钟 35K JOB4 10:36 15分钟 25K JOB5 10…

开发一款相亲交友小程序

uni-app框架&#xff1a;使用Vue.js开发跨平台应用的前端框架&#xff0c;编写一套代码&#xff0c;可编译到Android、小程序等平台。 框架支持:springboot/Ssm/thinkphp/django/flask/express均支持 前端开发:vue.js 可选语言&#xff1a;pythonjavanode.jsphp均支持 运行软件…