搜索
首页web前端js教程Node.js 的内存限制到底是多少?

What Exactly Is the Memory Limit of Node.js?

熟练掌握 Node.js API 可以让您快速入门,但深入了解 Node.js 程序的内存占用可以让您走得更远。

让我们首先通过 process.memoryUsage() 查看内存使用情况,每秒更新一次:

setInterval(() => { console.log('Memory Usage:', process.memoryUsage()); }, 1000);

由于输出以字节为单位,因此不方便用户使用。让我们通过将内存使用量格式化为 MB:
来修饰它

function formatMemoryUsageInMB(memUsage) {
    return {
        rss: convertToMB(memUsage.rss),
        heapTotal: convertToMB(memUsage.heapTotal),
        heapUsed: convertToMB(memUsage.heapUsed),
        external: convertToMB(memUsage.external)
    };
}

const convertToMB = value => {
    return (value / 1024 / 1024).toFixed(2) + ' MB';
};

const logInterval = setInterval(() => {
    const memoryUsageMB = formatMemoryUsageInMB(process.memoryUsage());
    console.log(`Memory Usage (MB):`, memoryUsageMB);
}, 1000);

现在,我们每秒都可以得到以下输出:

Memory Usage (MB): {
  rss: '30.96 MB', // The actual OS memory used by the entire program, including code, data, shared libraries, etc.
  heapTotal: '6.13 MB', // The memory area occupied by JS objects, arrays, etc., dynamically allocated by Node.js
                      // V8 divides the heap into young and old generations for different garbage collection strategies
  heapUsed: '5.17 MB',
  external: '0.39 MB'
}

Memory Usage (MB): {
  rss: '31.36 MB',
  heapTotal: '6.13 MB',
  heapUsed: '5.23 MB',
  external: '0.41 MB'
}

我们都知道V8引擎的内存使用是有限的,不仅受到操作系统的内存管理和资源分配策略的限制,还受到其自身的设置的限制。

使用 os.freemem(),我们可以看到操作系统有多少可用内存,但这并不意味着 Node.js 程序可以获取所有内存。

console.log('Free memory:', os.freemem());

对于 64 位系统,Node.js V8 默认最大旧空间大小约为 1.4GB。这意味着即使您的操作系统有更多可用内存,V8 也不会自动使用超过此限制的内存。

提示:可以通过设置环境变量或启动 Node.js 时指定参数来更改此限制。例如,如果您希望 V8 使用更大的堆,可以使用 --max-old-space-size 选项:

node --max-old-space-size=4096 your_script.js

这个值需要根据你的实际情况和场景来设置。比如说,如果你有一台大内存的机器,独立部署,还有很多小内存的机器分布式部署,这个值的设置肯定会有所不同。

让我们通过无限地向数组填充数据来运行测试,直到内存溢出,看看什么时候会发生。

const array = [];
while (true) {
    for (let i = 0; i 



<p>这是我们直接运行程序时得到的结果。添加一段数据后,程序崩溃了。<br>
</p>

<pre class="brush:php;toolbar:false">Memory Usage (MB): {
  rss: '2283.64 MB',
  heapTotal: '2279.48 MB',
  heapUsed: '2248.73 MB',
  external: '0.40 MB'
}
Memory Usage (MB): {
  rss: '2283.64 MB',
  heapTotal: '2279.48 MB',
  heapUsed: '2248.74 MB',
  external: '0.40 MB'
}


#
# Fatal error in , line 0
# Fatal JavaScript invalid size error 169220804
#
#
#
#FailureMessage Object: 0x7ff7b0ef8070

困惑吗?不是限制1.4G吗?为什么使用2G以上?实际上,Node.js 的 1.4GB 限制是 V8 引擎的历史限制,适用于早期的 V8 版本和某些配置。在现代 Node.js 和 V8 中,Node.js 会根据系统资源自动调整其内存使用情况。在某些情况下,它可能使用远超过 1.4GB 的空间,特别是在处理大型数据集或运行内存密集型操作时。

当我们将内存限制设置为 512M 时,当 rss 达到 996 MB 左右时就会溢出。

Memory Usage (MB): {
  rss: '996.22 MB',
  heapTotal: '993.22 MB',
  heapUsed: '962.08 MB',
  external: '0.40 MB'
}
Memory Usage (MB): {
  rss: '996.23 MB',
  heapTotal: '993.22 MB',
  heapUsed: '962.09 MB',
  external: '0.40 MB'
}



[22540:0x7fd27684d000]     1680 ms: Mark-sweep 643.0 (674.4) -> 386.8 (419.4) MB, 172.2 / 0.0 ms  (average mu = 0.708, current mu = 0.668) allocation failure; scavenge might not succeed
[22540:0x7fd27684d000]     2448 ms: Mark-sweep 962.1 (993.2) -> 578.1 (610.7) MB, 240.7 / 0.0 ms  (average mu = 0.695, current mu = 0.687) allocation failure; scavenge might not succeed




FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory

综上所述,更准确的来说,Node.js 的内存限制是指堆内存限制,即 JS 对象、数组等可以占用的最大内存,由 V8 分配。

堆内存的大小决定了Node.js进程可以占用多少内存吗?不!继续阅读。

我可以将 3GB 文件放入 Node.js 内存中吗?

我们在测试中看到,在程序崩溃之前,数组只能容纳 2GB 多一点。那么,如果我有一个 3GB 的文件,我不能把它一次性放入 Node.js 内存吗?

你可以的!

我们通过process.memoryUsage()看到了一个外部内存,它被Node.js进程占用,但没有被V8分配。只要你把3GB的文件放在那里,就没有内存限制。如何?您可以使用缓冲区。 Buffer 是 Node.js 的 C 扩展模块,它使用 C 来分配内存,而不是 JS 对象和数据。

这是一个演示:

setInterval(() => { console.log('Memory Usage:', process.memoryUsage()); }, 1000);

即使你分配了3GB内存,我们的程序仍然可以顺利运行,而我们的Node.js程序占用了超过5GB内存,因为这个外部内存不是Node.js限制的,而是操作系统对分配内存的限制到线程(所以不能胡作非为,连 Buffer 都会内存不足;本质是用 Streams 来处理大数据)。

在 Node.js 中,Buffer 对象的生命周期与 JavaScript 对象相关联。当 JavaScript 对 Buffer 对象的引用被删除时,V8 垃圾收集器会将该对象标记为可回收,但 Buffer 对象的底层内存不会立即释放。通常,当调用 C 扩展的析构函数时(例如 Node.js 中的垃圾回收过程),这部分内存会被释放。然而,这个过程可能与V8的垃圾收集并不完全同步。

function formatMemoryUsageInMB(memUsage) {
    return {
        rss: convertToMB(memUsage.rss),
        heapTotal: convertToMB(memUsage.heapTotal),
        heapUsed: convertToMB(memUsage.heapUsed),
        external: convertToMB(memUsage.external)
    };
}

const convertToMB = value => {
    return (value / 1024 / 1024).toFixed(2) + ' MB';
};

const logInterval = setInterval(() => {
    const memoryUsageMB = formatMemoryUsageInMB(process.memoryUsage());
    console.log(`Memory Usage (MB):`, memoryUsageMB);
}, 1000);

总结:Node.js 内存使用量由 JS 堆内存使用量(由 V8 的垃圾回收决定)和 C 内存分配组成

为什么堆内存分为新代和老代?

分代垃圾收集策略在现代编程语言的实现中非常普遍! Ruby、.NET 和 Java 中都可以找到类似于分代垃圾收集的类似策略。当垃圾回收发生时,常常会导致“stop the world”的情况,这不可避免地影响程序性能。然而,这种设计是考虑到性能优化的。

  • 不同的对象寿命 在程序开发过程中,很大一部分变量是临时的,用于完成特定的本地计算任务。这样的变量更适合Minor GC,即新一代GC。新一代内存中的对象主要通过Scavenge算法进行垃圾回收。 Scavenge 算法将堆内存一分为二,即 From 和 To(经典的空间换时间权衡。由于它们的生存时间较短,因此不会消耗大量内存)。

内存分配时,发生在 From 内。在垃圾回收期间,会检查 From 中的活动对象并将其复制到 To,然后释放非活动对象。在下一轮收集中,To 中的活动对象将被复制到 From,此时 To 会转变为 From,反之亦然。在每个垃圾收集周期中,From 和 To 都会交换。该算法在复制过程中仅复制存活对象,从而避免内存碎片的产生。
那么,变量的活跃度是如何确定的呢?可达性分析开始发挥作用。以以下对象为例:

  • globalObject:全局对象。
  • obj1:被globalObject直接引用的对象。
  • obj2:obj1引用的对象。
  • obj3:一个孤立的对象,没有任何其他对象的引用。

在可达性分析的背景下:

  • globalObject 作为根对象,本质上是可访问的。
  • obj1,由于被globalObject引用,也是可达的。
  • obj2 被 obj1 引用,因此也是可访问的。
  • 相比之下,obj3 由于缺少根对象或其他可到达对象的任何引用路径,因此被判定为不可到达,因此符合回收条件。

诚然,引用计数可以作为一种辅助手段。然而,在存在循环引用的情况下,它无法准确确定对象的真实活性。

在老年代内存中,对象通常不太活跃。但当老年代内存满了时,会通过Mark-Sweep算法触发老年代内存的清理(Major GC)。

标记-清除算法包括两个阶段:标记和清除。在标记阶段,V8 引擎会遍历堆中的所有对象并标记存活的对象。在清扫阶段,仅清除未标记的对象。该算法的优点是,由于老年代中死亡对象的比例相对较小,因此清理阶段消耗的时间相对较少。但它的缺点是只清除而不压缩,可能会导致内存空间不连续,不方便为大对象分配内存。

这个缺点会导致内存碎片,需要使用另一种算法,Mark-Compact。该算法将所有存活对象移至一端,然后一举消灭边界右侧的无效内存空间,从而获得完整且连续的可用内存空间。它解决了 Mark-Sweep 算法可能导致的内存碎片问题,但代价是移动大量活动对象会花费更多时间。

如果您觉得这篇文章有用,请点赞。 :D

以上是Node.js 的内存限制到底是多少?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
JavaScript,C和浏览器之间的关系JavaScript,C和浏览器之间的关系May 01, 2025 am 12:06 AM

引言我知道你可能会觉得奇怪,JavaScript、C 和浏览器之间到底有什么关系?它们之间看似毫无关联,但实际上,它们在现代网络开发中扮演着非常重要的角色。今天我们就来深入探讨一下这三者之间的紧密联系。通过这篇文章,你将了解到JavaScript如何在浏览器中运行,C 在浏览器引擎中的作用,以及它们如何共同推动网页的渲染和交互。JavaScript与浏览器的关系我们都知道,JavaScript是前端开发的核心语言,它直接在浏览器中运行,让网页变得生动有趣。你是否曾经想过,为什么JavaScr

node.js流带打字稿node.js流带打字稿Apr 30, 2025 am 08:22 AM

Node.js擅长于高效I/O,这在很大程度上要归功于流。 流媒体汇总处理数据,避免内存过载 - 大型文件,网络任务和实时应用程序的理想。将流与打字稿的类型安全结合起来创建POWE

Python vs. JavaScript:性能和效率注意事项Python vs. JavaScript:性能和效率注意事项Apr 30, 2025 am 12:08 AM

Python和JavaScript在性能和效率方面的差异主要体现在:1)Python作为解释型语言,运行速度较慢,但开发效率高,适合快速原型开发;2)JavaScript在浏览器中受限于单线程,但在Node.js中可利用多线程和异步I/O提升性能,两者在实际项目中各有优势。

JavaScript的起源:探索其实施语言JavaScript的起源:探索其实施语言Apr 29, 2025 am 12:51 AM

JavaScript起源于1995年,由布兰登·艾克创造,实现语言为C语言。1.C语言为JavaScript提供了高性能和系统级编程能力。2.JavaScript的内存管理和性能优化依赖于C语言。3.C语言的跨平台特性帮助JavaScript在不同操作系统上高效运行。

幕后:什么语言能力JavaScript?幕后:什么语言能力JavaScript?Apr 28, 2025 am 12:01 AM

JavaScript在浏览器和Node.js环境中运行,依赖JavaScript引擎解析和执行代码。1)解析阶段生成抽象语法树(AST);2)编译阶段将AST转换为字节码或机器码;3)执行阶段执行编译后的代码。

Python和JavaScript的未来:趋势和预测Python和JavaScript的未来:趋势和预测Apr 27, 2025 am 12:21 AM

Python和JavaScript的未来趋势包括:1.Python将巩固在科学计算和AI领域的地位,2.JavaScript将推动Web技术发展,3.跨平台开发将成为热门,4.性能优化将是重点。两者都将继续在各自领域扩展应用场景,并在性能上有更多突破。

Python vs. JavaScript:开发环境和工具Python vs. JavaScript:开发环境和工具Apr 26, 2025 am 12:09 AM

Python和JavaScript在开发环境上的选择都很重要。1)Python的开发环境包括PyCharm、JupyterNotebook和Anaconda,适合数据科学和快速原型开发。2)JavaScript的开发环境包括Node.js、VSCode和Webpack,适用于前端和后端开发。根据项目需求选择合适的工具可以提高开发效率和项目成功率。

JavaScript是用C编写的吗?检查证据JavaScript是用C编写的吗?检查证据Apr 25, 2025 am 12:15 AM

是的,JavaScript的引擎核心是用C语言编写的。1)C语言提供了高效性能和底层控制,适合JavaScript引擎的开发。2)以V8引擎为例,其核心用C 编写,结合了C的效率和面向对象特性。3)JavaScript引擎的工作原理包括解析、编译和执行,C语言在这些过程中发挥关键作用。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

SublimeText3 英文版

SublimeText3 英文版

推荐:为Win版本,支持代码提示!

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

功能强大的PHP集成开发环境

螳螂BT

螳螂BT

Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

mPDF

mPDF

mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),