我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Node.js中的垃圾回收机制是什么

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Node.js中的垃圾回收机制是什么

这篇“Node.js中的垃圾回收机制是什么”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Node.js中的垃圾回收机制是什么”文章吧。

GC,Garbage Collection,垃圾回收。在编程中,一般指的是内存自动回收机制,会定时将不需要用到的数据进行清除。

Node.js 底层使用了 V8 引擎。V8 是 Google 开源的一款高性能 JavaScript 引擎,使用了 C++ 进行编写。

Node.js 的内存主要分成三部分:

  • 代码空间:存放代码段的地方;

  • 栈:函数调用栈产生的临时变量,为一些基本类型,比如数字、字符串、布尔值,以及对象引用(保存的是地址,不保存对象本身)。

  • 堆:存放对象等数据。

堆内存

Node.js 底层使用的是 V8,下面讲解一下 V8 的内存回收机制。

首先 JS 中所有的对象都会保存在堆内存中。在创建进程的时候,会分配一个初始大小的堆内存,然后我们的对象就会放到里面。

当对象越来越多,堆内存会不够用,此时堆内存会动态地扩大。如果到达一个最大限制(现在通常是 4GB),就会堆内存溢出的错误,然后终止 Node.js 进程。

新生代与老生代

V8 首先将内存分成两部分,或者说两个生代(generation):

  • 新生代(yong generation):保存一些存活时间较短的对象;

  • 老生代(old generation):保存存活时间长或者长驻的对象。

新生代很小,这里会存放一些存活时间很短的对象,通常它们会被频繁地回收(比如函数的调用栈的一些临时对象)。

新生代可通过 node --max-semi-space-size=SIZE index.js 修改新生代的大小,单位为 MB。

另外,老生代则通过 --max-old-space-size=SIZE 来设置

新生代的 Scavenge 算法

新生代使用了 Scavenge 算法,是一种基于 copy(复制)的算法。

新生代会分成两个空间,这种空间称为 semispace,它们为:

  • From 空间:新声明的对象会放入这里

  • To 空间:用作搬移的空间

新声明的对象会放入到 From 空间中,From 空间的对象紧密排布,通过指针,上一对象紧贴下一个对象,是内存连续的,不用担心内存碎片的问题。

所谓内存碎片,指的是空间分配不均匀,产生大量小的连续空间,无法放入一个大对象。

当 From 空间快满了,我们就会遍历找出活跃对象,将它们 copy 到 To 空间。此时 From 空间其实就空了,然后我们将 From 和 To 互换身份。

如果一些对象被 copy 了多次,会被认为存活时间较长,将被移动到老生代中。

这种基于 copy 的算法,优点是可以很好地处理内存碎片的问题,缺点是会浪费一些空间作为搬移的空间位置,此外因为拷贝比较耗费时间,所以不适合分配太大的内存空间,更多是做一种辅助 GC。

Mark-Sweep 和 Mark-Compact

老生代的空间就比新生代要大得多了,放的是一些存活时间长的对象,用的是 Mark-Sweep (标记清除)算法。

首先是标记阶段。从根集 Root Set(执行栈和全局对象)往上找到所有能访问到的对象,给它们标记为活跃对象。

标记完后,就是清除阶段,将没有标记的对象清除,其实就是标记一下这个内存地址为空闲。

这种做法会导致 空闲内存空间碎片化,当我们创建了一个大的连续对象,就会找不到地方放下。这时候,就要用 Mark-Compact(标记整理)来将碎片的活跃对象做一个整合。

Mark-Compact 会将所有活跃对象拷贝移动到一端,然后边界的另一边就是一整块的连续可用内存了。

考虑到 Mark-Sweep 和 Mark-Compact 花费的时间很长,且会阻塞 JavaScript 的线程,所以通常我们不会一次性做完,而是用 增量标记 (Incremental Marking)的方式。也就是做断断续续地标记,小步走,垃圾回收和应用逻辑交替进行。

另外,V8 还做了并行标记和并行清理,提高执行效率。

Node.js中的垃圾回收机制是什么

查看内存相关信息

我们可以通过 process.memoryUsage 方法拿到内存相关的一些信息。

process.memoryUsage();

输出内容为:

{  rss: 35454976,  heapTotal: 7127040,  heapUsed: 5287088,  external: 958852,  arrayBuffers: 11314}

说明

  • rss:常驻内存大小(resident set size),包括代码片段、堆内存、栈等部分。

  • heapTotal:V8 的堆内存总大小;

  • heapUsed:占用的堆内存;

  • external:V8 之外的的内存大小,指的是 C++ 对象占用的内存,比如 Buffer 数据。

  • arrayBuffers:ArrayBufferSharedArrayBuffer 相关的内存大小,属于 external 的一部分。

以上数字的单位都是字节。

测试最大内存限制

写一个脚本,用一个定时器,让一个数组不停地变大,并打印堆内存使用情况,直到内存溢出。

const format = function (bytes) {  return (bytes / 1024 / 1024).toFixed(2) + " MB";};const printMemoryUsage = function () {  const memoryUsage = process.memoryUsage();  console.log(    `heapTotal: ${format(memoryUsage.heapTotal)}, heapUsed: ${format(      memoryUsage.heapUsed    )}`  );};const bigArray = [];setInterval(function () {  bigArray.push(new Array(20 * 1024 * 1024));  printMemoryUsage();}, 500);

需要特别注意的是,不要用 Buffer 做测试。

因为 Buffer 是 Node.js 特有的处理二进制的对象,它不是在 V8 中的实现的,是 Node.js 用 C++ 另外实现的,不通过 V8 分配内存,属于堆外内存。

我使用电脑是 macbook pro M1 Pro,Node.js 版本为 v16.17.0,使用的 V8 版本是 9.4.146.26-node.22(通过 process.versions.v8 得到)。

输出结果为(省略了一些多余的信息):

heapTotal: 164.81 MB, heapUsed: 163.93 MBheapTotal: 325.83 MB, heapUsed: 323.79 MBheapTotal: 488.59 MB, heapUsed: 483.84 MB...heapTotal: 4036.44 MB, heapUsed: 4003.37 MBheapTotal: 4196.45 MB, heapUsed: 4163.29 MB<--- Last few GCs --->[28033:0x140008000]    17968 ms: Mark-sweep 4003.2 (4036.4) -> 4003.1 (4036.4) MB, 2233.8 / 0.0 ms  (average mu = 0.565, current mu = 0.310) allocation failure scavenge might not succeed[28033:0x140008000]    19815 ms: Mark-sweep 4163.3 (4196.5) -> 4163.1 (4196.5) MB, 1780.3 / 0.0 ms  (average mu = 0.413, current mu = 0.036) allocation failure scavenge might not succeed<--- JS stacktrace --->FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory...

可以看到,是在 4000 MB 之后超出了内存上限,发生堆溢出,然后退出了进程。说明在我的机器上,默认的最大内存为 4G。

实际最大内存和它运行所在的机器有关,如果你的机器的内存大小为 2G,最大内存将设置为 1.5G。

以上就是关于“Node.js中的垃圾回收机制是什么”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注编程网行业资讯频道。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Node.js中的垃圾回收机制是什么

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Node.js中的垃圾回收机制是什么

这篇“Node.js中的垃圾回收机制是什么”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Node.js中的垃圾回收机制是什么
2023-07-04

php7中垃圾回收机制是什么

小编给大家分享一下php7中垃圾回收机制是什么,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!php有什么用php是一个嵌套的缩写名称,是英文超级文本预处理语言,它
2023-06-08

PHP中的垃圾回收机制是什么

这篇文章主要讲解了“PHP中的垃圾回收机制是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“PHP中的垃圾回收机制是什么”吧!相信只要入门学习过一点开发的同学都知道,不管任何编程语言,一个
2023-06-20

Python中的垃圾回收机制是什么

本篇文章给大家分享的是有关Python中的垃圾回收机制是什么,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。GC作为现代编程语言的自动内存管理机制,专注于两件事:1. 找到内存中
2023-06-17

PHP垃圾回收机制是什么

本篇内容主要讲解“PHP垃圾回收机制是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“PHP垃圾回收机制是什么”吧!PHP的垃圾回收机制垃圾回收机制是一种动态存储分配的方案。它会自动释放程序不
2023-06-20

Java垃圾回收机制是什么

这篇文章主要介绍“Java垃圾回收机制是什么”,在日常操作中,相信很多人在Java垃圾回收机制是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java垃圾回收机制是什么”的疑惑有所帮助!接下来,请跟着小编
2023-06-17

python垃圾回收机制是什么

Python的垃圾回收机制是自动化的,它使用了引用计数和循环垃圾收集两种方法。1. 引用计数:Python中的每个对象都有一个引用计数器,用来记录有多少个引用指向该对象。当引用计数器为0时,说明没有任何引用指向该对象,对象就会被垃圾回收机制
2023-08-14

go垃圾回收机制是什么

go语言中的垃圾回收机制是指自动管理内存分配和释放的机制。在Go语言中,开发者不需要手动去分配和释放内存,而是由垃圾回收机制自动进行管理。Go语言的垃圾回收器采用了并发标记清除(concurrent mark and sweep)的算法,
2023-10-25

jvm回收垃圾的机制是什么

JVM(Java虚拟机)使用自动垃圾回收(Garbage Collection)机制来管理和回收不再使用的对象的内存。以下是JVM垃圾回收的机制:1. 引用计数:这是一种最简单的垃圾回收机制,它通过对每个对象维护一个引用计数器来记录当前有多
2023-08-30

Java 垃圾回收机制的原理究竟是什么?(java垃圾回收机制的原理是什么)

在Java编程中,垃圾回收机制是一个非常重要的概念。它负责自动管理内存,回收不再被引用的对象,以避免内存泄漏和提高程序的性能。本文将详细介绍Java垃圾回收机制的原理。一、什么是垃圾回收垃圾回收是一种自动内存管理技术,它
Java 垃圾回收机制的原理究竟是什么?(java垃圾回收机制的原理是什么)
Java2024-12-22

jvm垃圾回收机制指的是什么

这篇文章主要介绍“jvm垃圾回收机制指的是什么”,在日常操作中,相信很多人在jvm垃圾回收机制指的是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”jvm垃圾回收机制指的是什么”的疑惑有所帮助!接下来,请跟
2023-07-05

Java垃圾回收机制的原理是什么

本篇内容主要讲解“Java垃圾回收机制的原理是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java垃圾回收机制的原理是什么”吧!Java 垃圾回收机制1. 垃圾回收主要关注 Java 堆图
2023-06-15

js垃圾回收机制的原理是什么

这篇“js垃圾回收机制的原理是什么”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“js垃圾回收机制的原理是什么”文章吧。前言大
2023-06-27

jvm垃圾回收机制的原理是什么

JVM(Java虚拟机)的垃圾回收机制是自动管理内存的一种机制,它通过识别和释放不再被程序使用的对象,以防止内存泄漏和内存溢出等问题。JVM的垃圾回收机制基于以下原理:1. 引用计数:JVM使用引用计数来跟踪对象的引用数。每当一个对象被引用
2023-09-25

Python垃圾回收机制的原理是什么

Python的垃圾回收机制是自动进行的,它基于引用计数的原理以及循环垃圾收集。引用计数:Python中的每个对象都有一个引用计数值,表示指向该对象的引用个数。当创建一个对象时,引用计数为1。当对象被引用时,引用计数增加;当对象不再被引用时,
2023-10-20

PHP的垃圾回收机制的原理是什么

这篇文章将为大家详细讲解有关PHP的垃圾回收机制的原理是什么,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。PHP的基本GC概念PHP语言同其他语言一样,具有垃圾回收机制。那么今天我们要为大家
2023-06-17

PHP的垃圾回收机制

PHP垃圾回收机制PHP采用引用计数机制管理内存,跟踪变量指向对象的次数。当引用计数降至0时,对象将被释放。循环引用会阻止对象释放,导致内存泄漏。PHP还提供弱引用、对象销毁器和垃圾回收循环等机制来帮助清理垃圾。虽然垃圾回收机制通常有效,但在处理大数据集时或出现循环引用时可能会影响性能。优化垃圾回收可以通过避免循环引用、使用弱引用和显式garbagecollection等措施来实现。
PHP的垃圾回收机制
2024-04-25

python语法之垃圾回收机制是什么

本篇内容介绍了“python语法之垃圾回收机制是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一 引入解释器在执行到定义变量的语法时,会
2023-06-30

PHP的垃圾回收机制

一、原理 php5和php7的垃圾回收机制都是利用引用计数。 二、php5和php7不同点 1、PHP5标量数据类型会计数,PHP7标量数据类型不再计数,不需要单独分配内存。 2、PHP7的zval 需要的内存不再是单独从堆上分配,不再自己存储引用计数。 3、
PHP的垃圾回收机制
2016-04-04

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录