我们应该感谢相遇,无论结局是喜是悲....
Node.js内存溢出-process out of memory 问题的处理
  • 首页 > IT技术
  • 作者:起点终站
  • 2019年5月27日 19:10 星期一
  • 浏览:1105
  • 字号:
  • 评论:1
  • Node.js做密集型运算,或者所操作的数组、对象本身较大时,容易出现内存溢出的问题,这是由于Node.js的运行环境-V8引擎导致的。如果经常有较大数据量运算等操作,需要对Node.js运行环境限制有充分的了解。


    1. 内存溢出问题

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


    密集型运算

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

    for (var i = 0; i < 10000000; i++) {
      ((i) => {
    	var site = {};
    	site.name = 'IT笔录';
    	site.domain = 'itbilu.com';
    
    	// 这里是一个保存或更新等操作
    	setTimeout(()=>{
    	  console.log(i, site);
    	}, 0)
      })(i)
    }


    操作的数据量较大

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

    var sites = [];
    
    for (var x=0;x<5000;x++){
      var site=[];
      for (var y=0;y<5000;y++){
      	site = [y, 'IT笔录', 'itbilu.com'];
        sites.push(site);
      }
    }
    
    
    

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

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

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

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


    3. 解决内存溢出问题

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


    1. 使用process.nextTick()防止事件堆积

    process.nextTick()会在本次事件循环结束后,立即开始下次事件循环。这样可以使V8获得内存回收的机会,有效解决过多事件堆积造成的内存溢出。

    我们可以使用process.nextTick()方法处理:

    forLoops(0);
    
    function forLoops(i) {
      if(i<10000000)
      {
        var site = {};
        site.name = 'IT笔录';
        site.domain = 'itbilu.com';
    
        // 这里是一个保存或更新等操作
        setTimeout(()=>{
    	  console.log(i, site);
        }, 0)
        process.nextTick(forLoops, i+=1);
      }
    }

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


    2. 增加V8内存空间

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

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

    node --max-old-space-size=4096 app


    3. 使用非V8内存

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

    • V8内存:数组、字符串等JavaScript内置对象,运行时使用“V8内存”
    • 系统内存:Buffer是一个Node.js的扩展对象,使用底层的系统内存,不占用V8内存空间。与之相关的文件系统fs和Stream流操作,都不会占用V8内存。

    在程序允许的情况下,应该将数据保存在Buffer中,而不是转换成字符串等JS对象,这样可以避免V8内存的过多占用。


      您阅读这篇文章共花了:  
    本文作者:起点终站      文章标题: Node.js内存溢出-process out of memory 问题的处理
    本文地址:https://blog.hellozwh.com/?post=434
    版权声明:若无注明,本文皆为“起点终站”原创,转载请保留文章出处。
    丘八06月03日
    好文章,好好学习,天天向上,支持一下
    返回顶部| 首页| 手气不错| 网站地图| sitemap| 装逼生成器| 站长介绍|

    Copyright © 2016-2019 起点终站 闽ICP备16011094号-1