JavaScript 内存管理

时间:2024-10-17 16:52:50

   JavaScript内存管理主要涉及到堆(Heap)和栈(Stack),以及任务队列(Task Queue)和调

用栈(Call Stack)。

  1.堆(Heap)

  •     存储对象与分配的动态内存。
  •     当你创建一个新的对象{},数组[],或者任何其他复杂类型时,它们会被分配在堆上。

2.栈(Stack)

  •   存储基本类型数据(如Numbers, Strings, Booleans, Null, Undefined)和指向堆上对象的指针
  •   当你创建一个变量并将一个原始值赋值给它时,如let a = 5;,这个值会被存储在栈上。
  •   调用函数时,函数的环境(包括局部变量)会被推入调用栈。

3.任务队列(Task Queue)

  • 存储异步操作的回调,如setTimeout, setInterval, Promise, Fetch等。
  • 当这些异步操作完成时,其回调函数会被推入任务队列等待执行。

4.调用栈(Call Stack)

  • 当JavaScript运行时,它会按顺序执行调用栈的函数。

  • 当执行完所有同步代码或遇到异步操作时,会将控制权交给浏览器的事件循环

  在JavaScript中,调用栈(call stack)是一个存储函数调用的地方,其中JavaScript引擎使用这个栈来管理代码执行的顺序。当调用函数时,它会被添加到调用栈的顶部。当函数执行完毕并返回时,它会从调用栈的顶部移除。

  当调用栈达到最大大小时,会引发"栈溢出"错误。这通常发生在无限递归或处理大量的同步调用时。

  在浏览器环境中,当调用栈为空时,事件循环开始运行。事件循环是JavaScript运行时的一部分,它处理各种事件(例如用户的点击,API调用的返回,setTimeout的时间到达等),当这些事件处理完毕后,它将控制权交还给调用栈,继续执行代码。

JavaScript 的内存管理主要是通过垃圾回收机制来自动处理的,其中最著名的垃圾回收算法是引用计数和标记清除。

  1. 引用计数: 当一个对象被创建时,系统会记录有多少变量指向这个对象,如果这个数量降到0,那么这个对象就会被垃圾回收器回收。但是这种方法有一个问题,就是循环引用,如果两个对象相互引用,那么这两个对象的引用计数永远不会降为0,因此这种方法在现代浏览器中已经不再使用。

  2. 标记清除: 这是现代浏览器使用的垃圾回收算法。工作原理是,当代码执行过程中,运行环境会追踪哪些变量正在被使用,然后在执行垃圾回收时,清除未被追踪的变量。

在JavaScript中,可以使用new关键字创建对象,使用delete操作符删除对象的属性,或者将对象的引用设置为null来手动释放内存