Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >笔记:记一次解决V8使用内存超过默认限制

笔记:记一次解决V8使用内存超过默认限制

作者头像
Peter谭金杰
发布于 2020-05-09 09:34:07
发布于 2020-05-09 09:34:07
3.6K00
代码可运行
举报
运行总次数:0
代码可运行

起因:

混合TypeScript和javaScript开发,完美升级老项目,这个老项目是一个巨无霸项目,非常庞大,是集团公司的最核心项目


遇到问题:

webpack打包时候遇到

对于曾经开发过C++,addon的我,熟悉的味道,下面有一些v8的字符出现,感觉应该是v8层面出现了问题


报错解决:

任何报错,先看第一个报错,解决顶部的报错。


问题定位:

JS堆栈跟踪,javaScript heap out of memory ,内存不足


隐约记得,v8对使用内存的限制,64位系统是1.4G,32位系统是0.7G,Buffer属于C++层面,不会被限制。但是长度会被限制,当Buffer被创建时候就会被判断长度

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
https://github.com/nodejs/node/blob/master/lib/buffer.js#L90-L101

node.js官网对长度的文档描述:

这种简单问题不做阐述,继续


项目之前纯js开发,现在接入ts,为什么同样的电脑,之前可以运行,现在却内存不足?

答案:

  1. 首先要从内存回收说起,为什么要限制内存使用,因为1.4G普遍够用,再一个,内存回收是会阻塞主线程。300MB大概是0.5s,这里在我开发桌面端即时通讯应用时,经常会遇到这个问题。一个20万人的群,一直以1000条/秒的速度推送消息到桌面端,时间一长,Node接入主进程层面就不行了。CPU和内存占用会飙升,要做很多特殊优化处理
  2. 我在ts中配置允许使用js,那么意味着要增加一个编译ts成js的过程,这个编译过程肯定要占用大部分内存。所以之前纯js项目不会出现这个问题,
  3. 网上大部分都是手动更改webpack的源码文件,达到修改v8使用内存限制的目的,但是作为跨平台的产品来说,必须支持两点:工程化+自动化、可跨平台无感知的情况才能使用
  4. v8的内存回收机制影响,跟上面第二点搭配,当然,现在这套东西,已经被面试官问烂了(就跟考试让你背古诗一样),我面试是不会问这些无聊的问题。作为一个Node.js的深度使用者,我觉得是C++出生的人,可能会在Node.js走得更远,它更像是一个库,一个前端制作工具的库。如果要深入后端,走得更远,建议还是要学习java与c++
    • *

解决办法:

Node.js的8.0版本以上可以这样调整

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
export NODE_OPTIONS=--max_old_space_size=4096

也可以使用自动化、工程化配置插件

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
increase-memory-limit

由于一些部署服务器上的配置未知,在测试过后,我选择了后者,编写了新的构建命令,这样达到效果。


难道做API工程师,不可能的,我的原则,使用第三方库,框架必须看它的 源码实现,包括Node.js

increase-memory-limit

源码只有几十行代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#!/usr/bin/env node
const path = require('path');
const glob = require('glob');
const fs = require('fs');

const maxOldSpaceSize = process.env.LIMIT || 10240;
const cwd = process.cwd() + path.sep;

glob(path.join(cwd, "node_modules", ".bin", "*"), function (err, files) {

  files.forEach(file => {
    // readFileSync will crash on non-files. Skip over these
    let stat = fs.lstatSync(fs.realpathSync(file));
    if (!stat.isFile()) {
      return;
    }
    if (file.indexOf('increase-memory-limit') >= 0) {
      return;
    }
    // build scripts will hand in LIMIT via cross-env
    // avoid updating it while we are running it
    if (file.indexOf('cross-env') >= 0) {
      return;
    }
    let contents = fs.readFileSync(file).toString();
    let lines = contents.split('\n')

    let patchedContents = "";

    for (var index = 0; index < lines.length; index++) {
      var line = lines[index];
      if (line.startsWith("if [") || line.startsWith("@IF") || line.indexOf ('has_node') !== -1) {
        patchedContents += line + "\n";
      } else {
        patchedContents += line.replace(/node(\.exe)?\b(?: \-\-max\-old\-space\-size\=[0-9]+)?/, `node$1 --max-old-space-size=${maxOldSpaceSize}`) + "\n";
      }
    }

    fs.writeFileSync(file, patchedContents);
    console.log(`'${file.replace(cwd, "")}'`, "written successfully.");
  });

});

它依赖glob这个库

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
https://www.npmjs.com/package/glob

首先读取LIMIT配置

然后拿到node启动的命令路径(配置path.sep针对跨平台,cwd返回的路径做处理分隔)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var glob = require("glob")

通过glob这库,传入路径和配置后,拿到包含文件数组,然后读取文件流信息并且toString()

最核心的源码文件就是下面这个

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
   patchedContents += line + "\n";
    } else {
      patchedContents += line.replace(/node(\.exe)?\b(?: \-\-max\-old\-space\-size\=[0-9]+)?/, `node$1 --max-old-space-size=${maxOldSpaceSize}`) + "\n";
    }
  }

  fs.writeFileSync(file, patchedContents);
  console.log(`'${file.replace(cwd, "")}'`, "written successfully.");

通过正则将读取的文件流信息,匹配相应的配置后,替换内容后同步写入(因为必须同步写入!!!否则项目无法启动,不能异步此处)


目前有一个系列写作计划,面试成长系列和踩坑成长系列同步进行,喜欢的话点个在看,关注下公众号:前端巅峰

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

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

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

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Vue内存溢出问题解决方法
引起内存泄漏的原因有不少,本文就介绍webpack 运行 npm run build 内存溢出 JavaScript heap out of memory内存溢出的错误。vue-cli3.0构建的项目,开发过程中,可能会遇到内存溢出的情况,改动一点代码,代码编译,进程就会断掉。
前端逗逗飞
2021/04/30
4.9K0
Vue内存溢出问题解决方法
项目构建内存溢出了?看看 Node 内存限制
看到内存溢出这个关键字,我们一般都会考虑到是因为 Node.js 内存不够导致的。
皮小蛋
2021/05/06
4.6K0
项目构建内存溢出了?看看 Node 内存限制
Node.js内存管理和V8垃圾回收机制
对于 Node.js 服务端研发的同学来说,关于垃圾回收、内存释放这块不需要向 C/C++ 的同学那样在创建一个对象之后还需要手动创建一个 delete/free 这样的一个操作进行 GC(垃圾回收), Node.js 与 Java 一样,由虚拟机进行内存自动管理。
五月君
2019/07/12
3K0
Node.js内存管理和V8垃圾回收机制
保护 Node.js 项目的源代码
SaaS(Software as a Service,软件即服务),是一种通过互联网提供软件服务的模式。服务提供商会全权负责软件服务的搭建、维护和管理,使得他们的客户从这些繁琐的工作中解放出来。对于许多中小型企业而言,SaaS 是采用先进技术的最好途径。
保利威视频云
2020/05/07
3.5K0
保护 Node.js 项目的源代码
如何调整 Node.js 项目配置以解决内存分配问题
在使用 Node.js 开发和运行应用程序时,偶尔会遇到 FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory 的错误。这通常意味着应用程序需要分配的内存超过了 V8 引擎的默认限制,导致程序崩溃。本文将详细探讨如何通过修改 package.json 文件和其他相关手段,优化内存分配,确保 Node.js 应用的稳定运行。
编程小妖女
2025/01/08
3690
如何调整 Node.js 项目配置以解决内存分配问题
Node.js内存溢出时如何处理?
Node.js 做密集型运算,或者所操作的数组、对象本身较大时,容易出现内存溢出的问题,这是由于 Node.js 的运行环境依赖 V8 引擎导致的。如果经常有较大数据量运算等操作,需要对 Node.js 运行环境限制有充分的了解。
coder_koala
2019/08/21
4.9K0
Node.js内存溢出时如何处理?
如何用Node.js实现给Markdown文件标题加数字序号?
你好,我是喵喵侠。作为一名技术创作者,Markdown我每次写文章都会用到,它可以很方便的帮助我书写文章,让我专注于内容,不需要刻意注重排版。
喵喵侠
2024/07/31
2250
如何用Node.js实现给Markdown文件标题加数字序号?
【译】容器环境下 Node.js 的内存管理
在docker容器中运行Node.js应用程序时,传统的内存参数调整并不总是按预期工作。本文我们将阐述在基于容器的Node.js应用程序内存参数调优中并不总是有效的原因,并提供了在容器环境中使用Node.js应用程序时可以遵循的建议和最佳实践。
五月君
2019/10/14
2.1K0
day038:V8 引擎如何进行垃圾内存的回收?
JS 语言不像 C/C++, 让程序员自己去开辟或者释放内存,而是类似Java,采用自己的一套垃圾回收算法进行自动的内存管理。作为一名资深的前端工程师,对于JS内存回收的机制是需要非常清楚, 以便于在极端的环境下能够分析出系统性能的瓶颈,另一方面,学习这其中的机制,也对我们深入理解JS的闭包特性、以及对内存的高效使用,都有很大的帮助。
用户3806669
2021/03/10
7890
关于node项目打包内存溢出JS stacktrace
问题 <--- Last few GCs ---> 58003 ms: Mark-sweep 1350.6 (1434.6) -> 1350.5 (1434.6) MB, 753.0 / 0.0 ms [allocation failure] [GC in old space requested]. 58751 ms: Mark-sweep 1350.5 (1434.6) -> 1350.5 (1434.6) MB, 747.6 / 0.0 ms [allocation failure] [G
用户1437675
2022/03/24
2.9K0
关于node项目打包内存溢出JS stacktrace
Node理论笔记:内存控制
JavaScript和Java一样是由垃圾回收机制来进行自动内存管理的,对于浏览器,几乎不需要考虑内存回收的问题,但服务器对性能更为敏感,内存管理的好坏、垃圾回收是否优良,都会对服务造成影响。再node中,这一切都与JavaScript引擎——V8相关。
Ashen
2020/06/01
6720
深入解析Node.js:V8引擎、事件驱动和非阻塞式I/O
🎉欢迎来到架构设计专栏~探索Java中的静态变量与实例变量深入解析Node.js:V8引擎、事件驱动和非阻塞式I/O
IT_陈寒
2023/12/14
2740
深入解析Node.js:V8引擎、事件驱动和非阻塞式I/O
Jenkins前端打包内存溢出问题
公司项目vue构建,体积比较庞大,在Jenkins上构建时,有新的内容提交时,第一次npm run build必失败,报内存溢出错误
全栈程序员站长
2021/05/19
4.7K0
uniapp小程序迁移到TS
我一直在做的小程序就是 山科小站 也已经做了两年了,目前是用uniapp构建的,在这期间也重构好几次了,这次在鹅厂实习感觉受益良多,这又得来一次很大的重构,虽然小程序功能都是比较简单的功能,但是这好不容易实习学到的东西得学以致用,那就继续在小程序上动手吧哈哈。这次实习收获最大倒不是怎么迁移到TS,而是一些组件设计的概念以及目录结构设计上的东西,不过这都是在之后重写组件的时候要做的东西了。回到正题,小程序是用uniapp写的,毕竟还是比较熟悉Vue语法的,这次迁移首先是要将小程序从HBuilderX迁移到cli版本,虽然用HBuilderX确实是有一定的优点,但是拓展性比较差,这些东西还是得自己折腾折腾,迁移到cli版本完成后,接下来就是要慢慢从js过渡到ts了,虽然是Vue2对ts支持相对比较差,但是至少对于抽离出来的逻辑是可以写成ts的,可以在编译期就避免很多错误,另外自己使用cli创建可以搞一些其他功能,毕竟只要不操作DOM的话一般还是在用常用的js方法,例如可以尝试接入Jest单元测试等。
WindRunnerMax
2021/10/15
1.5K0
《深入浅出Node.js》-内存控制
本章学习 V8 的垃圾回收机制以及如何高效使用内存,内存泄漏以及如何排查内存泄漏。
李振
2021/11/26
8350
Node.js 是如何做 GC (垃圾回收)的?
GC,Garbage Collection,垃圾回收。在编程中,一般指的是内存自动回收机制,会定时将不需要用到的数据进行清除。
前端西瓜哥
2022/12/21
8730
Node.js 是如何做 GC (垃圾回收)的?
30个有用的npm包
很早之前,软件工程师就通过减少程序中重复代码来显著加速开发过程。Nodejs生态通过npm包的形式复用代码,目前累计有超过100多万个开源可用的包。其中一些流行的包每周下载量破千万,是许多应用程序的基础,从小型宠物项目到知名科技初创公司都有使用到。
腾讯新闻前端团队
2021/08/30
3.2K0
node内存泄漏以及定位
IMWeb前端团队
2017/12/29
8330
node内存泄漏以及定位
有意思的 Node.js 内存泄漏问题
作者:elvinpeng,腾讯 WXG 前端开发工程师 Node.js 使用的是 V8 引擎,会自动进行垃圾回收(Garbage Collection,GC),因而写代码的时候不需要像 C/C++ 一样手动分配、释放内存空间,方便不少,不过仍然需要注意内存的使用,避免造成内存泄漏(Memory Leak)。 内存泄漏往往非常隐蔽,例如下面这段代码你能看出来是哪儿里有问题吗? let theThing = null; let replaceThing = function() {   const new
腾讯技术工程官方号
2020/08/21
6.3K2
V8内存管理及垃圾回收机制
基本类型数据(Number, Boolean, String, Null, Undefined, Symbol, BigInt)保存在在栈内存中。引用类型数据保存在堆内存中,引用数据类型的变量是一个指向堆内存中实际对象的引用,存在栈中。
木子星兮
2020/07/16
9270
相关推荐
Vue内存溢出问题解决方法
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验