搜索
首页web前端js教程Nodejs内存治理步骤详解

Nodejs内存治理步骤详解

May 22, 2018 am 09:21 AM
javascriptnodejs详解

这次给大家带来Nodejs内存治理步骤详解,Nodejs内存治理的注意事项有哪些,下面就是实战案例,一起来看一下。

s运行的宿主环境不同,相应的对内存治理的要求也不一样,当宿主环境是浏览器时,由于网页的运行时间短,且只运行在用户的机器上(相当于分布式),即使内存使用过多或者存在一定的内存泄漏,也并不会对终端用户产生太大的影响。当宿主环境编程服务器(Node)时,情况就大不相同了,本身代码运行在固定的几台机器(集中式)上,而且运行的时间是长时间运行,一旦内存治理不好出现了内存膨胀甚至是内存泄漏的情况的话,就会出现服务器端响应时间变长甚至是服务crash的情况。

Nodejs是基于V8构建的,所以在Node中使用的JavaScript对象基本上(Buffer就不是)都是通过V8来进行分配和管理的。V8在占用内存大小上做了限制(64位操作系统,单个Node进程可使用的最大堆内存大小约为1.5GB)。即使服务器的内存很大,但是由于V8的这种限制,导致Node无法充分利用服务器的资源。即便如此,为什么V8要做这样的限制呢?做这样限制的原因其实是与垃圾回收机制相关,以1.5GB的垃圾回收堆内存堆为例,V8做一次小的垃圾回收需要50ms以上,做一次全量的垃圾回收甚至要1s以上,要知道垃圾回收过程中JavaScript线程是要处于暂停执行的状态,太长的暂行时间对于后端服务的性能是会产生较大影响的,所以出于这方面考虑,V8对堆内存做了限制。即便如此,V8还是提供了可以自定义堆内存大小的方式(--max-old-pace-size),old-space代表老生代、new-space代表新生代。

node --max-old-space-size=xxx index.js //单位为MB
// 之前还可以通过-max-new-space-size来定义新生代堆大小,现在已经不可以了

当由于内存泄漏导致服务器一直频繁重启的时候,建议先调大堆内存大小来为定位问题争取时间,毕竟服务响应慢总比直接返回错误页对于用户而言会更好接受一点。

为什么需要老生代和新生代?

老生代和新生代其实是分代式垃圾回收机制里面的不同的分代,因为没有一种垃圾回收算法能够胜任所有的场景,不同的对象生存周期其实需要不同的回收策略才能达到最好的效果,所以V8采用分代式垃圾回收机制,降对象按的存活时间进行不同的分代,然后对不同分代(新生代、老生代)的内存施以更适合也更好的算法。

新生代中的对象存活时间较短,而老生代中的对象存活时间较长甚至是常驻内存。基于此所以设计的新生代的内存普遍要比老生代的内存小很多,V8中新生代最大内存是32M(64位系统为例),老生代最大内存是1400MB。V8实际使用的堆内存大小是新生代+老生代所用内存之和(1432MB),但是V8最大值其实是比使用的内存对大小额外大了32M(1464MB)

新生代如何做垃圾回收?

新生代的采用名叫Scavenge的垃圾回收算法。在Scavenge的具体实现中,主要采用了Cheney算法,Cheney算法通过将新生代堆一分为二,一个使用(From semispace),一个空闲(To semispace)。创建对象的时候,现在From空间中进行分配,当需要进行垃圾回收时,就检查From空间中的存活对象,然后将存活的对象拷贝到To空间,同时清空From空间,并将From和To互换,整个垃圾回收过程中就是将存活对象在两个seispace之间进行复制。对于生命周期短的场景存活对象在整个对象中占比较小,所以Scavenge采用的是复制存活的对象,但是Scavenge只能利用堆内存一半的空间,这是典型的用空间换时间的体现。

当一个对象经过多次垃圾回收依然存活的话,就会被认为是生命周期较长的对象,一方面新生代堆比较小,另一方面重复复制生命周期长的对象也很没有效率,所以对于生命周期长的对象会被移到老生代中去。新生代对象移动到老生代有两个对象:1.对象是否是生命周期较长的对象(已经经历过垃圾回收)2.To空间使用占比是否超过了25%。限制25%的原因是由于垃圾回收完成后To会变成From,如果不做限制的话可能会出现From很快被用光的情况,出现频繁的垃圾回收,也会影响效率。

老生代如何做垃圾回收?

老生代由于存活对象占较大比重,不适合对存活对象进行操作,使用Scavenge算法就不太合适了,因此老生代采用了Mark-Sweep和Mark-Compact相结合的方式。

Mark-Sweep分为标记和清除两个阶段,在标记阶段遍历堆中所有对象,标记活着的对象,然后在清除阶段未被标记的对象将会被清除掉。Mark-Sweep解决了内存释放的问题但是由于没有像Scavenge那样复制对象的操作导致内存碎片化不连续。而Mark-Compact就是用来解决内存碎片化问题的。Mark-Compact会将存活的对象往一端移动,移动完成后直接清理掉边界外的内存,这样就有大段的连续可用内存了,但是由于涉及到对象的移动,因此Mark-Compact的速度要比Mark-Sweep慢了。V8主要使用Mark-Sweep,只有当空间不足以对新生代中今生过来的对象进行分配时才使用Mark-Compact。

垃圾回收过程中会导致应用程序暂停执行,由于新生代本身空间较小,且要复制的存活对象占比也少,因此即便执行全量垃圾回收也影响不大,但是老生代空间很大,存活对象也多,执行一次全量垃圾回收对于应用程序暂停会是一个比较长的时间,因此V8将老生的标记改成了增量更新的方式,使得标记和应用程序交替执行直到标记完成,然后垃圾回收再执行后面的清理工作。注意清理工作并不是增量的。

开发者可以指定强制垃圾回收吗?

答案是可以了,在启动node服务的时候使用--expose-gc flag

$ node --expose-gc file.js

这样全局对象上就有了执行垃圾回收的函数

global.gc();

推荐更安全的写法

function forceGC()
 if (global.gc) {
  global.gc();
 } else {
  console.warn('No GC hook! Start your program as `node --expose-gc file.js`.');
 }
}

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

Vue页面骨架屏注入步骤详解

解决node修改后需频繁手动重启如何处理

以上是Nodejs内存治理步骤详解的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
JavaScript在行动中:现实世界中的示例和项目JavaScript在行动中:现实世界中的示例和项目Apr 19, 2025 am 12:13 AM

JavaScript在现实世界中的应用包括前端和后端开发。1)通过构建TODO列表应用展示前端应用,涉及DOM操作和事件处理。2)通过Node.js和Express构建RESTfulAPI展示后端应用。

JavaScript和Web:核心功能和用例JavaScript和Web:核心功能和用例Apr 18, 2025 am 12:19 AM

JavaScript在Web开发中的主要用途包括客户端交互、表单验证和异步通信。1)通过DOM操作实现动态内容更新和用户交互;2)在用户提交数据前进行客户端验证,提高用户体验;3)通过AJAX技术实现与服务器的无刷新通信。

了解JavaScript引擎:实施详细信息了解JavaScript引擎:实施详细信息Apr 17, 2025 am 12:05 AM

理解JavaScript引擎内部工作原理对开发者重要,因为它能帮助编写更高效的代码并理解性能瓶颈和优化策略。1)引擎的工作流程包括解析、编译和执行三个阶段;2)执行过程中,引擎会进行动态优化,如内联缓存和隐藏类;3)最佳实践包括避免全局变量、优化循环、使用const和let,以及避免过度使用闭包。

Python vs. JavaScript:学习曲线和易用性Python vs. JavaScript:学习曲线和易用性Apr 16, 2025 am 12:12 AM

Python更适合初学者,学习曲线平缓,语法简洁;JavaScript适合前端开发,学习曲线较陡,语法灵活。1.Python语法直观,适用于数据科学和后端开发。2.JavaScript灵活,广泛用于前端和服务器端编程。

Python vs. JavaScript:社区,图书馆和资源Python vs. JavaScript:社区,图书馆和资源Apr 15, 2025 am 12:16 AM

Python和JavaScript在社区、库和资源方面的对比各有优劣。1)Python社区友好,适合初学者,但前端开发资源不如JavaScript丰富。2)Python在数据科学和机器学习库方面强大,JavaScript则在前端开发库和框架上更胜一筹。3)两者的学习资源都丰富,但Python适合从官方文档开始,JavaScript则以MDNWebDocs为佳。选择应基于项目需求和个人兴趣。

从C/C到JavaScript:所有工作方式从C/C到JavaScript:所有工作方式Apr 14, 2025 am 12:05 AM

从C/C 转向JavaScript需要适应动态类型、垃圾回收和异步编程等特点。1)C/C 是静态类型语言,需手动管理内存,而JavaScript是动态类型,垃圾回收自动处理。2)C/C 需编译成机器码,JavaScript则为解释型语言。3)JavaScript引入闭包、原型链和Promise等概念,增强了灵活性和异步编程能力。

JavaScript引擎:比较实施JavaScript引擎:比较实施Apr 13, 2025 am 12:05 AM

不同JavaScript引擎在解析和执行JavaScript代码时,效果会有所不同,因为每个引擎的实现原理和优化策略各有差异。1.词法分析:将源码转换为词法单元。2.语法分析:生成抽象语法树。3.优化和编译:通过JIT编译器生成机器码。4.执行:运行机器码。V8引擎通过即时编译和隐藏类优化,SpiderMonkey使用类型推断系统,导致在相同代码上的性能表现不同。

超越浏览器:现实世界中的JavaScript超越浏览器:现实世界中的JavaScriptApr 12, 2025 am 12:06 AM

JavaScript在现实世界中的应用包括服务器端编程、移动应用开发和物联网控制:1.通过Node.js实现服务器端编程,适用于高并发请求处理。2.通过ReactNative进行移动应用开发,支持跨平台部署。3.通过Johnny-Five库用于物联网设备控制,适用于硬件交互。

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脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热工具

SecLists

SecLists

SecLists是最终安全测试人员的伙伴。它是一个包含各种类型列表的集合,这些列表在安全评估过程中经常使用,都在一个地方。SecLists通过方便地提供安全测试人员可能需要的所有列表,帮助提高安全测试的效率和生产力。列表类型包括用户名、密码、URL、模糊测试有效载荷、敏感数据模式、Web shell等等。测试人员只需将此存储库拉到新的测试机上,他就可以访问到所需的每种类型的列表。

EditPlus 中文破解版

EditPlus 中文破解版

体积小,语法高亮,不支持代码提示功能

禅工作室 13.0.1

禅工作室 13.0.1

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

SublimeText3 英文版

SublimeText3 英文版

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

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )专业的PHP集成开发工具