对象分配

所有的JS对象都是通过堆来进行分配的。使用process.memoryUsage()查看使用情况Node.js 中文网文档

process.memoryUsage()
{ rss: ,
heapTotal: ,
heapUsed: ,
external: }
// 单位 字节
// rss (resident set size) 常驻进程内存 所有内存占用
// heapTotal 已申请堆内存
// heapUsed 已使用堆内存
// external c++对象绑定到js的内存

内存限制

内存限制主要原因是v8的垃圾回收制度。1.5GB内存做一次小的回收需要50MS,做一次非增量性回收需要1S以上,并且这会使JS线程暂停。因此限制内存。

V8的堆组成

V8的堆由一系列区域组成:

新生代区:大多数对象的创建被分配在这里,这个区域很小,但垃圾回收非常频繁,独立于其它区。

老生代指针区:包含大部分可能含有指向其它对象指针的对象。大多数从新生代晋升(存活一段时间)的对象会被移动到这里。

老生代数据区:包含原始数据对象(没有指针指向其它对象)。Strings、boxed numbers以及双精度unboxed数组从新生代中晋升后被移到这里。

大对象区:这里存放大小超过其它区的大对象。每个对象都有自己mmap内存。大对象不会被回收。

代码区:代码对象(即包含被JIT处理后的指令对象)存放在此。唯一的有执行权限的区域(代码过大也可能存放在大对象区,此时它们也可被执行,但不代表大对象区都有执行权限)。

Cell区、属性Cell区以及map区:包含cell、属性cell以及map。每个区都存放他们指向的相同大小以及相同结构的对象。

v8在64位系统下只能使用1.4GB内存,在32位系统下只能使用0.7GB内存。

如何解除内存限制?

利用堆外内存: 使用Buffer类。Buffer 性能相关部分由C++实现。Buffer教程

在启动node时,传递--max-old-space-size=4096 (调整老生代内存限制,单位为mb。--max-new-space-size 已经不可用了)

使用stream处理大文件 stream教程

官方建议:it is recommended that you split your single process into several workers if you are hitting memory limits. (拆分进程)

垃圾回收机制

V8的垃圾回收有如下几个特点
当处理一个垃圾回收周期时,暂停所有程序的执行。(stop-the-world 全停顿)  

在大多数垃圾回收周期,每次仅处理部分堆中的对象,使暂停程序所带来的影响降至最低。(增量标记等算法) 

准确知道在内存中所有的对象及指针,避免错误地把对象当成指针所带来的内存泄露。(标记指针法:在每个指针的末位预留一位来标记这个字代表的是指针或数据。)

在V8中,对象堆被分为两个部分:新创建的对象所在的新生代,以及在一个垃圾回收周期后存活的对象被提升到的老生代。
如果一个对象在一个垃圾回收周期中被移动,那么V8将会更新所有指向此对象的指针。

内存泄漏

谷歌:什么是内存泄漏

百度:什么是内存泄漏

常见原因 1.缓存 2.队列消费不及时 3.作用域未释放

1 : 缓存

var cache = {};
function set (key, value){
cache[key] = value;
}

2 : 无限增长数组

var arr = [];
function x (value){
arr.push(value);
}

3: 无限重连导致的内存泄漏

const net = require('net');
let client = new net.Socket(); function connect() {
client.connect(26665, '127.0.0.1', function callbackListener() {
console.log('connected!');
});
} //第一次连接
connect(); client.on('error', function (error) {
// console.error(error.message);
}); client.on('close', function () {
//console.error('closed!');
//泄漏代码
client.destroy();
setTimeout(connect, 1);
});

泄漏产生的原因其实也很简单:event.js 核心模块实现的事件发布/订阅本质上是一个js对象结构(在v6版本中为了性能采用了new EventHandles(),并且把EventHandles的原型置为null来节省原型链查找的消耗),因此我们每一次调用 event.on 或者 event.once 相当于在这个对象结构中对应的 type 跟着的数组增加一个回调处理函数。

那么这个例子里面的泄漏属于非常隐蔽的一种:net 模块的重连每一次都会给 client 增加一个 connect事件 的侦听器,如果一直重连不上,侦听器会无限增加,从而导致泄漏。

4: 测试:

var run = function () {
var str = new Array(1000000).join('*');
var doSomethingWithStr = function () {
if (str === 'something')
console.log("str was something");
};
doSomethingWithStr();
};
setInterval(run, 1000);

Node内存限制与垃圾回收的更多相关文章

  1. 深入理解Node.js中的垃圾回收和内存泄漏的捕获

    深入理解Node.js中的垃圾回收和内存泄漏的捕获 文章来自:http://wwsun.github.io/posts/understanding-nodejs-gc.html Jan 5, 2016 ...

  2. V8 内存管理和垃圾回收机制总结

    这篇文章主要介绍 V8 的内存管理和垃圾回收知识. V8 内存管理及垃圾回收机制浅析 由于 V8 引擎的原因,Node 在操作大内存对象时受到了一些限制,在 64 位的机器上,默认最大操作的对象大小约 ...

  3. C#内存管理与垃圾回收

    垃圾回收还得从根说起,就像生儿育女一样. 根:根是一个位置,存放一个指针,该指针指向托管堆中的一个对象,或是一个空指针不指向任何对象,即为null.根存在线程栈或托管堆中,大部分的跟都在线程栈上,因为 ...

  4. 使用虚幻引擎中的C++导论(四-内存管理与垃圾回收)(终)

    使用虚幻引擎中的C++导论(四)(终) 第一,这篇是我翻译的虚幻4官网的新手编程教程,原文传送门,有的翻译不太好,但大体意思差不多,请支持我O(∩_∩)O谢谢. 第二,某些细节操作,这篇文章省略了,如 ...

  5. Java之美[从菜鸟到高手演变]之JVM内存管理及垃圾回收

    很多Java面试的时候,都会问到有关Java垃圾回收的问题,提到垃圾回收肯定要涉及到JVM内存管理机制,Java语言的执行效率一直被C.C++程序员所嘲笑,其实,事实就是这样,Java在执行效率方面确 ...

  6. Java内存管理和垃圾回收

    笔记,深入理解java虚拟机 Java运行时内存区域 程序计数器,线程独占,当前线程所执行的字节码的行号指示器,每个线程需要记录下执行到哪儿了,下次调度的时候可以继续执行,这个区是唯一不会发生oom的 ...

  7. Java虚拟机内存模型及垃圾回收监控调优

    Java虚拟机内存模型及垃圾回收监控调优 如果你想理解Java垃圾回收如果工作,那么理解JVM的内存模型就显的非常重要.今天我们就来看看JVM内存的各不同部分及如果监控和实现垃圾回收调优. JVM内存 ...

  8. JVM的stack和heap,JVM内存模型,垃圾回收策略,分代收集,增量收集

    (转自:http://my.oschina.net/u/436879/blog/85478) 在JVM中,内存分为两个部分,Stack(栈)和Heap(堆),这里,我们从JVM的内存管理原理的角度来认 ...

  9. JVM内存管理及垃圾回收

    一.JVM内存的构 Java虚拟机会将内存分为几个不同的管理区,这些区域各自有各自的用途,根据不同的特点,承担不同的任务以及在垃圾回收时运用不同的算法.总体分为下面几个部分: 程序计数器(Progra ...

随机推荐

  1. WP追加字符串到文件

    #if DEBUG const string logfile = "demo.log"; try { using (var sw = new System.IO.StreamWri ...

  2. 解决 Firefox 火狐浏览器下载 .exe 文件卡住的问题 以及关闭测试版cache2

    解决 Firefox 火狐浏览器下载 .exe 文件卡住的问题 在firefox浏览器地址栏里输入:about:config 点“我保证会小心”,显示firefox的高级配置列表 在配置页面的搜索框里 ...

  3. SQL Sever删除外键

    declare @sql varchar(max), @tab_name varchar(128), @fk_name varchar(128);declare c cursor forselect ...

  4. eclipse配置lombok

    原文:http://wsj356428476.iteye.com/blog/1655032 1.下载Lombok.jar https://projectlombok.org/ 2.运行Lombok.j ...

  5. android中shape的属性

    <shape> <!– 实心 –> <solid android:color=”#ff9d77″/> <!– 渐变 –> <gradient an ...

  6. 20165210 Java第三次实验报告

    20165210 实验二 敏捷开发与XP实践 一.敏捷开发与XP实践-1 实验要求: http://www.cnblogs.com/rocedu/p/4795776.html, Eclipse的内容替 ...

  7. 统计日志中ip出现的次数

    grep -r 'GET /weixin/weixin_izp/index.html' ./chunyun.access.log > ~/access.log cat access.log |a ...

  8. Busybox shell脚本修改密码

    /****************************************************************************** * Busybox shell脚本修改密 ...

  9. Java继承与接口

    public class test { public static void main(String[] args) { // TODO Auto-generated method stub B b= ...

  10. 电话圈(floyd)

    题意: 如果两个人相互打电话,则说他们在同一个电话圈里.例如,a打给b,b打给c,c打给d,d打给a,则这4个人在同一个圈里:如果e打给f但f不打给e,则不能推出e和f在同一个电话圈里,输出所有电话圈 ...