问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

nodejs怎么占内存那么多

发布网友 发布时间:2022-04-22 01:26

我来回答

2个回答

懂视网 时间:2022-05-14 18:41

本篇文章给大家带来的内容是关于nodejs垃圾回收的详细介绍,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

nodejs的垃圾回收机制是由v8引擎自动管理的。

nodejs的内存限制

在一般的后端语言(php)来说,内存的使用上是没有限制的,但对于nodejs来说只能使用系统的部分----64位系统为1.4G,32位系统位0.7G。这时如果你要处理个3G文件进行数据分析,即使系统的内存为8G,在该nodejs进程内存还是会溢出。

造成上面这个问题主要是因为nodejs是基于v8的,nodejs是通过v8自己的方式来管理内存的。那v8为什么要限制堆内存的大小呢?原因有2:

1、表层原因:v8是为浏览器设计的,不大可能遇到大内存的情景。

2.深层原因:v8垃圾回收机制的限制。以1.5G的堆内存为例,v8做一次小的垃圾回收需要50ms,做一次非增量的垃圾回收要1s。垃圾回收时会引起js的线程的暂停,在这样的时间花销下,应用的性能、响应能力会直线下降。

内存限制是可以打开的:
--max-old-space-size(老生代)
--max-new-space-size(新生代)
v8堆内存大小 = 老生代 + 新生代

v8垃圾回收机制
v8垃圾回收主要是基于分代式垃圾回收机制。按对象的存活时间将内存的垃圾回收进行不同的分代,分别对不同的分代内存进行不同的算法。

新生代--->存活时间较短的对象
老生代--->存活时间较长或常驻内存的对象
上面也说过,nodejs堆内存的大小是新生代内存空间加上老生代内存空间。

新生代算法
新生代主要是通过scavenge算法进行垃圾回收。

这是一种采用复制的方式来实现垃圾回收,将堆内存一分为二,每个空间称为semispace。在这2个semispace空间中,只有一个处于使用中(称为from空间),另一个处于空闲中(称为to空间)。开始分配时首先从from空间开始,当开始垃圾回收时,也是从from空间开始检查存活对象,把存活对象复制到to空间,而非存活对象占用的空间就会被释放。完成复制后,from空间和to空间角色对调。
从上面的过程可以知道,scavenge的缺点就是只使用了一半的堆内存,牺牲空间获取时间。

老生代通过mark-sweep、mark-comopact算法。

mark-sweep标记清除,分为标记、清除2个阶段。mark-sweep先在标记阶段遍历堆内存中的所有对象,并标记存活的对象;在清除阶段把没有被标记的对象清除。可以看出,scavenge只复制存活的对象,mark-sweep只清理死亡的对象。因为在新生代中存活的对象占用小部分,而在老生代中死亡对象占用小部分,这是这2中算法高效的原因。

Mark-compact标记整理,mark-sweep中会出现一个问题,在回收后,对内存会出现不连续的状态(内存碎片)。内存碎片会对后续的内存分配造成影响,因为会有这样一种情况:需要分配个大内存,而所有内存碎片都无法完成分配,这会提前触发垃圾回收,而这个回收时不必要的。Mark-compact是在Mark-sweep基础上演变而来的,它主要区别在于:对象被标记后,在整理的过程中会将存活的对象都往一端移动,移动完成后直接清除。

小结:在正常的使用过程中,v8的内存限制还是够用的,但nodejs的垃圾回收、单线程还是会影响性能。想要高性能,需要让垃圾回收尽量小。在实际的开发中要老生代对象的使用,如实现web服务的会话(session),一般会通过内存来存储(数组),在访问量大的情况下会导致老生代对象剧增,有可能造成溢出。如果要处理大内存的数据,比如读取3G的文件,我们会通过可读流的pipe()方法,这样就不会受到v8内存的限制影响,提高了nodejs程序的健壮性。

热心网友 时间:2022-05-14 15:49

node基于v8构建,所以在node中使用的js对象基本上都是通过v8自己的方式来进行分配和管理的。 
在v8中,所有的js对象都是通过堆来进行分配的。

process.memoryUsage();
{
rss:24473600,
heapTotal: 7331840,
heapUsed: 5736952,
external: 8727
}

v8内存分代 
v8中,主要将内存分为新生代和老生代。新生代中为存活时间较短的对象,老生代中为存活时间较长的对象。

新生代垃圾回收: 
新生代中的对象主要通过Scavenge算法进行垃圾回收。将新生代中的内存空间一分为二,处于使用状态的为From空间,处于闲置状态的为To空间。在进行垃圾回收时,检查From空间的存活对象并复制到To空间,非存活对象占用空间释放。之后From和To空间角色对调。

对象晋升: 
如果一个对象经历过一次新生代垃圾回收,或者To空间的内存占比超过25%,则此对象从新生代中移动到老生代中,此过程称为晋升。

老生代垃圾回收: 
主要采用Mark-Sweep(标记清除)和Mark-Compact(标记整理)两种方式进行垃圾回收。 
标记清除在标记阶段遍历堆中的所有对象,并标记活着的对象。随后的清除中只清除没有被标记的对象。会产生内存碎片。为解决这个问题,标记整理被提了出来,在对象被标记为死亡后,在整理的过程中,将活着的对象往一端移动,移动完成后直接清理掉边界外的内存。v8中混合使用这两种方法。一般在空间不足以对从新生代晋升过来的对象进行分配时,才使用标记整理。

高效使用内存: 
在js中无法立即回收的内存有闭包和全局变量引用这两种情况。此情况会导致新生代中的对象数量增多。


声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
火狐浏览器如何将网页保存为PDF文件 【亲测好用】网页下载保存为pdf u盘坏芯片坏能修吗-(u盘芯片坏了能修吗) 快捷糖水目录 微信上如何和男人撒娇? 去日本旅游要带什么好? 年月日电脑怎么设置表格excel表格出生日期列如何设置为年月日格式 ...一定要对女主好,宠她。要打包下载,谢谢亲。 空气净化器滤芯有酸味的原因 不同种类的蛋糕分别代表什么含义呢? js中如何彻底删除一个数组(内存),令数组长度等... javascript变量清空的问题? js 数组释放内存问题 cocos js 怎么清理内存 如何清理IE内存中的JS变量 ajax自动刷新,浏览器一直占用内存,不是释放,一... js内存不足怎么解决? 怎么解决内存泄漏js js 函数调用完了是否清除内存 js内存释放 在JavaScript中怎样释放对象占用的内存 nodejs占用内存太多怎么解决? 电信4G ctlte 的apn设置的详细参数? 中国电信用GMTDS接入点有没有影响? 联想台式机如何进入bios 千禾酱油是名牌吗? 各种品牌的酱油哪种比较好吃 联想按f几进入bios 中国酱油品牌前几名是那几个品牌 在中国市场目前什么酱油最好? javascript的setInterval函数用久了占用过多内存,... JavaScript 图片内存释放问题 javascript 在清除数组的元素的时候哪种方法不容易... 蚂蚁庄园星星球最高只有2个奖励,怎么才能变成3个... 支付宝星星球满分多少分 支付宝蚂蚁庄园星星球如何超过500分 蚂蚁庄园里星星球最高分数不是五百吗?怎么有好友玩... 支付宝的星星球能打到几分啊 更新后的星星球现在最高分是多少分了 支付宝蚂蚁庄园星星球怎么有888分 支付宝里蚂蚁庄园的星星球好友怎么玩到2000多分呢 支付宝新的星星球加速卡现在给10个了 支付宝小鸡星星球可以超过500分 排列组合中112排三位数怎么排,答案是先3乘2乘1在... 蚂蚁森林里星星球得多少分,才能领到饲料? 用0、1、2三个数字可以组成很多的自然数,将其从小... 蚂蚁庄园打球怎么会有800多分? 原神神里绫华是主c吗 从1到10000之间有几个整数,它们的各位数字之和都... 现在支付宝星星球每周一刷新,自己的最高纪录分数...