JS查漏补缺——内存管理和垃圾回收

简介: JS查漏补缺系列是我在学习JS高级语法时做的笔记,通过实践费曼学习法进一步加深自己对其的理解,也希望别人能通过我的笔记能学习到相关的知识点。这一次我们来理解一下面试题常考的内存管理和垃圾回收

认识内存管理

不管什么样的编程语言,在代码的执行过程中都是需要给它分配内存的,不同的是某些编程语言需要我们自己手动的管理内存(如:比如C、C++都是需要手动来管理内存的申请和释放的(malloc和free函数)某些编程语言会可以自动帮助我们管理内存(如:JavaScript通常情况下不需要手动管理

内存管理的生命周期

  • 申请内存
  • 使用内存
  • 释放内存

JS的内存分配

JavaScript会在定义变量时为我们分配内存
而对于变量,它有两种类型:简单数据类型(内存直接存的值),分别是Undefined,Null,Boolean,Number,String,Symbol,还有一种复杂数据类型(内存存的是引用地址):Object(对象、数组、函数)。
这两种类型在内存管理中分配内存的方式是不一样的:

  • 简单数据类型(基本类型)的值直接在栈空间进行分配,值与值之间是独立存在,修改一个变量的值不会影响其他变量的值
  • 复杂数据类型(引用类型)存在堆内存中,每创建一个对象,就会在堆内存中开辟出一个新的空间,而变量保存的对象的内存地址(对象的引用,如果两个变量保存的同一个对象,当一个变量改变属性值时,另一个变量的属性值也会变 )

简单数据类型的内存分配

// 定义变量
var a = 1;
var b = 2;

Snipaste_2022-08-18_09-46-36.png

复杂数据类型的内存分配

// 定义变量
const a = 1;
const b = 2;
const info {
  name: 'eureka',
  age: 100
}
function foo() {
  var c = 3;
  var d = 4;
  console.log(a+b);
}

Snipaste_2022-08-18_10-04-04.png

JS的内存释放

因为内存的大小是有限的,所以当内存不再需要的时候,我们需要对其进行释放,以便腾出更多的内存空间。

因为JS不用手动去释放内存,它有自己的垃圾回收机制(Garbage Collection,简称:GC),那JavaScript是怎么判断这个内存不再使用,进而被当成垃圾回收呢?

  • 当对象不再被引用时,JavaScript就认为它不再使用 (通过引用计数来确认)
  • 对象不能从根上访问到时,JavaScript也会把它认定为是垃圾 (通过标记清除来确认)

常见的GC算法——引用计数

当一个对象有一个引用指向它时,那么这个对象的引用就+1,当一个对象的引用为0时,这个对象就可以被销毁掉;

使用引用计数会有一个很严重的问题:循环引用。
循环引用指的是对象A中包含一个指向对象B的指针,而对象B中也包含一个指向对象A的引用,并且不能通过代码访问它们,这样它们的引用永远不会为0,垃圾回收机制不能将这两个对象释放,进而会造成内存泄露

let a = {
  name: 'a',
  dad: b
};

let b = {
 name: 'b',
 son: a
}
a = null;
b = null;

Snipaste_2022-08-18_11-45-41.png

常见的GC算法——标记清除

  • 这个算法是假定一个根对象(root object),垃圾回收器会定期从这个根开始,找所有从根开始有引用到的对象,对于哪些没有引用到的对象,就认为是不可用的对象;
  • 根对象在浏览器中是 window 对象,在 NodeJS 中是 global 对象,只有当程序退出或者关闭网页或者关闭浏览器的时候才会销毁。
  • 这个算法可以很好的解决循环引用的问题;

Snipaste_2022-08-18_12-38-19.png

参考文章:
JavaScript的内存管理 - MomentYY - 博客园

目录
相关文章
|
10小时前
|
算法 Java Go
Go vs Java:内存管理与垃圾回收机制对比
对比了Go和Java的内存管理与垃圾回收机制。Java依赖JVM自动管理内存,使用堆栈内存并采用多种垃圾回收算法,如标记-清除和分代收集。Go则提供更多的手动控制,内存分配与释放由分配器和垃圾回收器协同完成,使用三色标记算法并发回收。示例展示了Java中对象自动创建和销毁,而Go中开发者需注意内存泄漏。选择语言应根据项目需求和技术栈来决定。
|
10小时前
|
监控 算法 Java
Python内存管理与垃圾回收机制
【5月更文挑战第12天】了解Python内存管理与垃圾回收对编写高效稳定程序至关重要。Python自动管理内存,使用`malloc()`和`free()`分配和释放。引用计数跟踪对象引用,当引用计数为零时对象销毁。垃圾回收处理循环引用,采用分代回收算法。优化技巧包括避免循环引用、显式释放对象、使用生成器和迭代器。理解这些机制有助于避免内存泄漏,提高性能。通过示例代码,学习如何在实践中应用内存管理最佳实践和高级优化技巧,以及如何调试和诊断内存问题。在并发和异步编程中,需注意线程安全和异步内存管理。掌握这些知识能提升Python编程的效率和质量。
11 3
|
10小时前
|
JavaScript 前端开发 算法
JavaScript的垃圾回收机制通过标记-清除算法自动管理内存
【5月更文挑战第11天】JavaScript的垃圾回收机制通过标记-清除算法自动管理内存,免除开发者处理内存泄漏问题。它从根对象开始遍历,标记活动对象,未标记的对象被视为垃圾并释放内存。优化技术包括分代收集和增量收集,以提升性能。然而,开发者仍需谨慎处理全局变量、闭包、定时器和DOM引用,防止内存泄漏,保证程序稳定性和性能。
11 0
|
10小时前
|
JavaScript 前端开发 算法
JavaScript 的垃圾回收机制有一些潜在的缺点
【5月更文挑战第11天】JavaScript 的垃圾回收机制虽自动化管理内存,降低泄漏风险,但也存在性能开销、无法精确控制内存释放、全局变量和闭包可能导致内存泄漏、弱引用及循环引用问题。开发者需注意优化代码,避免这些问题,以充分利用垃圾回收机制并提升应用性能。
8 0
|
10小时前
|
JavaScript 前端开发 算法
了解JavaScript的垃圾回收机制
JavaScript的垃圾回收机制自动回收不再使用的内存,主要通过标记清除和引用计数算法。它从根对象开始遍历引用链,标记活跃对象并清理未标记的。引用计数算法在对象引用为零时回收,但循环引用会导致问题。现代垃圾回收器能处理循环引用,防止内存泄漏。示例代码展示了当大数组不再被引用时,垃圾回收机制自动清理内存。
|
10小时前
|
存储 算法 Java
了解Java内存管理与垃圾回收机制
了解Java内存管理与垃圾回收机制
8 0
|
10小时前
|
JavaScript 前端开发 算法
【JavaScript技术专栏】深入理解JavaScript垃圾回收机制
【4月更文挑战第30天】本文深入解析JavaScript的垃圾回收机制,旨在帮助开发者理解其工作原理。内容涵盖垃圾回收的概念、标记阶段、清除阶段,以及优化策略如增量回收、分代回收和并行回收。此外,还介绍了引用计数、标记-清除等常见垃圾回收算法,并讨论了内存泄漏的原因及解决方法,强调理解垃圾回收对编写高效代码的重要性。
|
10小时前
|
存储 缓存 JavaScript
【Web 前端】JS哪些操作会造成内存泄露?
【4月更文挑战第22天】【Web 前端】JS哪些操作会造成内存泄露?
|
10小时前
|
前端开发 JavaScript 算法
【Web 前端】JS垃圾回收机制?
【4月更文挑战第22天】【Web 前端】JS垃圾回收机制?
|
10小时前
|
前端开发 JavaScript 算法
JavaScript 内存管理的秘密武器:垃圾回收(下)
JavaScript 内存管理的秘密武器:垃圾回收(下)
JavaScript 内存管理的秘密武器:垃圾回收(下)