Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Node.js内存溢出时如何处理?

Node.js内存溢出时如何处理?

作者头像
coder_koala
发布于 2019-08-21 10:04:53
发布于 2019-08-21 10:04:53
5K00
代码可运行
举报
运行总次数:0
代码可运行

Node.js 做密集型运算,或者所操作的数组、对象本身较大时,容易出现内存溢出的问题,这是由于 Node.js 的运行环境依赖 V8 引擎导致的。如果经常有较大数据量运算等操作,需要对 Node.js 运行环境限制有充分的了解。

本文涵盖

  1. 内存溢出问题
  2. 为什么会内存溢出
    • 2.1 V8内存分配机制
    • 2.2 内存溢出的原因
  3. 如何解决内存溢出问题

1. 内存溢出问题

下面是我们在Node.js应用中经常遇到的两类内存溢出问题:

密集型运算

示例1:当我们需要批量处理一些数据(如:更新用户某项信息)时,我们可能需要一个较大的forwhile循环来完成所有的数据的更新,如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
for (var i = 0; i < 10000000; i++) {    ((i) => {        var site = {};        site.name = 'koala';        site.domain = '程序员成长指北';        // 这里是一个保存或更新等操作        setTimeout(()=>{            console.log(i, site);        }, 0)    })(i)}

操作的数据量较大

示例2:对象需要频繁的创建/销毁,或操作对象本身较大,如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var sites = [];
for (var x=0;x<5000;x++){    var site=[];    for (var y=0;y<5000;y++){        site = [y, 'koala', '程序员成长指北'];        sites.push(site);    }}

上面两类操作都会出现类似以下错误:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<--- Last few GCs --->
……
FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - process out of memory
Abort trap: 6

2. 为什么会内存溢出

2.1 V8内存分配机制

我们都知道,V8是 Google 在 Chrome 浏览器中使用的 JavaScript 引擎。而在浏览器环境中,运算一般不需要多大内存。

V8 对每个进程分配的运行内存,在32位系统中约为700MB,而在64位系统中约为1.4GB。

2.2 内存溢出的原因

Node.js 程序之所以会出内存溢出的情况,可以分为三方面的原因:1. V8本身分配的内存较小、2. JavaScript语言本身限制、3. 程序员使用不当。

示例1中,每次运算所需的内存量并不大,但由于for循环,造成V8内存不能及时释放。随着程序运行时候的增加,内存占用量会越来越大,并最终导致内存的溢出。

示例2中,可能所创建对象本身并没有超过内存限制。但是除对象本身外:创建对象、对象引用、Node.js程序本身等都需要内存空间,这样就很容易导致内存的溢出。

3. 解决内存溢出问题

在Node.js应用开发过程中,了解V8内存分配和JavaScript语言限制是Node程序的基本素质。我们应该在应用中权衡利弊,综合考虑内存与程序的运行效率。以下几点防止内存溢出的建议:

1. 使用 async/await防止事件堆积,变为同步操作

await将代码执行顺序变为了同步。这样可以使 V8 获得内存回收的机会,有效解决过多事件堆积造成的内存溢出。

我们可以使用await方法处理:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
async function dbFuc() {for (let i = 0; i < 10000000; i++) {    var site = {};    site.name = 'koala';    site.domain = '程序员成长指北';    // 这里是一个保存或更新等操作
    await  console.log(i, site);    }}dbFuc();

每次循环V8都会回收内存一次,因此内存不会再溢出。但这样做必然会造成运行效率的降低,而应该在速度在安全之间平衡,控制好循环的安全次数。

说明:实际开发中,上面这种虽然解决了内存溢出,但是仍然会造成进程阻塞,可以开启一个进程/线程来解决阻塞问题(具体可以看我的这篇文章深入理解Node.js 进程与线程(8000长文彻底搞懂))

2. 增加V8内存空间

Node.js提供了一个程序运行参数--max-old-space-size,可以通过该参数指定V8所占用的内存空间,这样可以在一定程度上避免程序内存的溢出。

如,我们可以在运行示例2程序时指定使用4G的内存:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
node --max-old-space-size=4096 app

3. 使用非V8内存

Node.js程序所使用的内存分为两类:

在程序允许的情况下,应该将数据保存在Buffer中,而不是转换成字符串等JS对象,这样可以避免V8内存的过多占用。(buffer可以看一下这篇文章Node进阶-探究不在V8堆内存中存储的Buffer对象

❤️ 看完三件事

如果你觉得这篇内容对你挺有启发,我想邀请你帮我三个小忙:

  1. 点个「在看」,让更多的人也能看到这篇内容(喜欢不点在看,都是耍流氓 -_-)
  2. 关注我的博客 https://github.com/koala-coding/goodBlog,让我们成为长期关系
  3. 关注公众号「程序员成长指北」,持续为你推送优质精选好文,也可以加我为好友哦。

在看点这里

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-08-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员成长指北 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
编辑精选文章
换一批
Android消息推送:手把手教你集成小米推送
继承自PushMessageReceiver(抽象类,继承自BroadcastReceiver),其作用主要是:
Carson.Ho
2019/02/22
4.8K0
Android OPPO推送服务集成(详细教学)
  为了丰富应用推送的场景和国产大厂设备,在我有这个条件的情况下,相关机型的文章我都会写一遍,这一篇就写一下OPPO的推送服务集成,我本身是荣耀的手机,OPPO是借的朋友的旧手机来测试对接的,手机名称是OPPO Find X,ColorOS版本是V7.1,Android版本是10,下面进入正文。
晨曦_LLW
2021/06/11
2.5K0
Android OPPO推送服务集成(详细教学)
Android 极光推送API
  发现现在的Android开发中很少有不用第三方SDK的,为什么呢?就是因为实现一个功能的速度快呀,比如说客服、聊天、直播等一些功能,用第三方SDK可以最快解决问题,我在实际开发中也对接过很多SDK,不过仔细写过这方便到的博客,前段时间我写了一个关于udesk SDK的文章,实现IM的,写的不算太详细,不过你如果看了也够用了,好了,进入正文。
晨曦_LLW
2022/05/10
1.6K0
Android 极光推送API
Android 对接极光推送
发现现在的Android开发中很少有不用第三方SDK的,为什么呢?就是因为实现一个功能的速度快呀,比如说客服、聊天、直播等一些功能,用第三方SDK可以最快解决问题,我在实际开发中也对接过很多SDK,不过仔细写过这方便到的博客,前段时间我写了一个关于udesk SDK的文章,实现IM的,写的不算太详细,不过你如果看了也够用了,好了,进入正文。
晨曦_LLW
2020/09/25
1.3K0
Android系统推送Hook实战
随着数据生产功能的逐渐稳定,工作重点开始从保证数据总量转移到了保证数据实效性上来了。传统的定时爬虫能比较轻松的把数据总量做起来,但是对于很多热点数据,却很难做到实时获取。
mythsman
2022/11/14
2.2K0
Android系统推送Hook实战
极光推送使用心得以及记录
最近项目遇到推送,与后台贱人于一合计,果断采用了极光推送。在使用过程中,有爽有不爽,特意再次记录下。
贺biubiu
2019/06/10
1.4K0
【Android应用开发】 推送原理解析 极光推送使用详解 (零基础精通推送)
转载请注明出处 : http://blog.csdn.net/shulianghan/article/details/45046283
韩曙亮
2023/03/27
2.8K0
【Android应用开发】 推送原理解析 极光推送使用详解 (零基础精通推送)
极光推送的简单实现方法
导入其jar包和so文件这点不再详解, 但是要注意的一点就是: 个人感觉极光的demo还是有些地方需要改进的, 不建议使用,但是里面的代码是需要我们自己拿的, 我这里主要就是拿到的服务器端发过来的消息推送。
胖虎哥
2023/05/10
1K0
极光推送的简单实现方法
使用Leancloud实现React Native App的消息推送(Push Notification)- Android篇
在上一篇文章 中我们详细讲解了用Leancloud实现iOS消息推送的流程,今天本文将继续讲解实现Android的消息推送。
MudOnTire
2019/05/26
3.4K0
Android 接入udesk SDK实现IM
创建好之后可以获得应用的APP Id和App Key,这两个值是要在Android中配置的
晨曦_LLW
2020/09/25
1K0
集成推送那点事-友盟/Mob-Flutter/FCM
这里就挑我用过的几个来做一个简单对比,毕竟鸡老大说了,连基本的论证对比都没,你还玩个锤子(我瞎编的)。
贺biubiu
2020/07/14
12.5K1
集成推送那点事-友盟/Mob-Flutter/FCM
Android推送的群魔乱舞
国内Android缺少Google的生态,如Google的Paly Store,Google Mobile Services(GSM)等,导致衍生出很多畸形的产业,比如五花八门的APP市场,光怪陆离的推送平台,这里要说的是推送平台。Google本身的GSM服务是包含一套推送在里面的,跟iOS系统的推送类似,它保证每台手机维护一个推送通道就能收到各方推送,但由于Google没法进入中国市场,国产Android基本上算被阉割了一个核心部件,由此衍生的种种弊端数不胜数,首当其冲的就是推送。
看书的小蜗牛
2020/07/23
1.9K0
Android热修复实践应用—AndFix
一直关注App的热修复的技术发展,之前做的应用也没用使用到什么热修复开源框架。在App的热修复框架没有流行之前,做的应用上线后发现一个小小的Bug,就要马上发一个新的版本。我亲身经历过一周发两个版本,真的折腾用户的节奏~~所以,要开始考虑引入热修复。下面记录使用开源框架阿里巴巴的AndFix过程。 实现的原理 这里说的不是热修复怎么实现修bug的原理,这里说的是怎么使用AndFix。如果你想了解更多的andFix实现原理,你可以参考下面的文章: https://github.com/alibaba/
非著名程序员
2018/02/02
8060
Android热修复实践应用—AndFix
Android使用后端云Bmob实现登录、注册及失物招领
最近在使用后端云Bmob对数据进行存储,目的是在不搭建服务器的前提下,能对Android应用的数据进行操作处理。
SoullessCoder
2019/08/07
3.4K1
Android使用后端云Bmob实现登录、注册及失物招领
【Android 进程保活】应用进程拉活 ( 双进程守护 + JobScheduler 保活 | 成功率最高 | 推荐使用 )
【Android 进程保活】应用进程拉活 ( JobScheduler 拉活 | JobScheduler 使用流程 | JobService 服务 | 不同版本兼容 | 源码资源 ) 博客中介绍了 JobScheduler 的用法 ;
韩曙亮
2023/03/29
2.5K0
【Android 进程保活】应用进程拉活 ( 双进程守护 + JobScheduler 保活 | 成功率最高 | 推荐使用 )
Android应用角标适配方法,源码在三星和华为上测试通过
一、应用的角标如下面的红点,提示用户有新的信息更新。角标,英语是badge,也就是“徽章,像章,奖章; 象征,标记”的意思。一般来说,应用的角标是用来标记有多少条提醒(Notification)没读(unread),一旦点击提示进应用阅读了,角标也会消失。
IT工作者
2022/05/20
1.4K0
Android自动连接指定的wifi,免密码或指定密码
遇到一个这样的要求:“不进行扫描操作,怎么对指定的免密码WIFI进行连接(之前没有连接过)”,于是动手写了一个Demo,如图所示未连接成功时的状态,第一个编辑框让用户输入SSID,第二个编辑框输入密码,密码可以根据实例情况输入,也可以不输入密码,因为有些Wifi免密码。这里的免密码不是指可以破解wifi密码。注意图片中手机顶部的wifi图标,是没有的,说明此时并没有打开手机的wifi。在手机上运行状态如下所示:
张果
2022/05/09
2.3K0
Android自动连接指定的wifi,免密码或指定密码
【Android学习】Android广播机制
在Android中实现广播,首先我们要在Manifest.xml文件中配置一个<receiver/>标签,这个标签必须有一个android:name属性,值为继承自BroadcastReceiver类的接收器类!这个标签还有一个子标签为<intent-filter/>,这个标签很重要,是指定接收器需要接收哪种广播。另外,还有配置一个用户权限:<uses-permission/>,具体的值可以参考官方API文档。
易寒
2021/12/23
5350
Android微信之登录授权(ShareSDK-AndroidStudio)
之前通过Eclipse来实现,那么Android Studio如何来实现呢? 先上个效果图
专注APP开发
2019/11/07
9570
Android微信之登录授权(ShareSDK-AndroidStudio)
推荐阅读
相关推荐
Android消息推送:手把手教你集成小米推送
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验