Node内存限制与垃圾回收
对象分配
所有的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内存限制与垃圾回收的更多相关文章
- 深入理解Node.js中的垃圾回收和内存泄漏的捕获
深入理解Node.js中的垃圾回收和内存泄漏的捕获 文章来自:http://wwsun.github.io/posts/understanding-nodejs-gc.html Jan 5, 2016 ...
- V8 内存管理和垃圾回收机制总结
这篇文章主要介绍 V8 的内存管理和垃圾回收知识. V8 内存管理及垃圾回收机制浅析 由于 V8 引擎的原因,Node 在操作大内存对象时受到了一些限制,在 64 位的机器上,默认最大操作的对象大小约 ...
- C#内存管理与垃圾回收
垃圾回收还得从根说起,就像生儿育女一样. 根:根是一个位置,存放一个指针,该指针指向托管堆中的一个对象,或是一个空指针不指向任何对象,即为null.根存在线程栈或托管堆中,大部分的跟都在线程栈上,因为 ...
- 使用虚幻引擎中的C++导论(四-内存管理与垃圾回收)(终)
使用虚幻引擎中的C++导论(四)(终) 第一,这篇是我翻译的虚幻4官网的新手编程教程,原文传送门,有的翻译不太好,但大体意思差不多,请支持我O(∩_∩)O谢谢. 第二,某些细节操作,这篇文章省略了,如 ...
- Java之美[从菜鸟到高手演变]之JVM内存管理及垃圾回收
很多Java面试的时候,都会问到有关Java垃圾回收的问题,提到垃圾回收肯定要涉及到JVM内存管理机制,Java语言的执行效率一直被C.C++程序员所嘲笑,其实,事实就是这样,Java在执行效率方面确 ...
- Java内存管理和垃圾回收
笔记,深入理解java虚拟机 Java运行时内存区域 程序计数器,线程独占,当前线程所执行的字节码的行号指示器,每个线程需要记录下执行到哪儿了,下次调度的时候可以继续执行,这个区是唯一不会发生oom的 ...
- Java虚拟机内存模型及垃圾回收监控调优
Java虚拟机内存模型及垃圾回收监控调优 如果你想理解Java垃圾回收如果工作,那么理解JVM的内存模型就显的非常重要.今天我们就来看看JVM内存的各不同部分及如果监控和实现垃圾回收调优. JVM内存 ...
- JVM的stack和heap,JVM内存模型,垃圾回收策略,分代收集,增量收集
(转自:http://my.oschina.net/u/436879/blog/85478) 在JVM中,内存分为两个部分,Stack(栈)和Heap(堆),这里,我们从JVM的内存管理原理的角度来认 ...
- JVM内存管理及垃圾回收
一.JVM内存的构 Java虚拟机会将内存分为几个不同的管理区,这些区域各自有各自的用途,根据不同的特点,承担不同的任务以及在垃圾回收时运用不同的算法.总体分为下面几个部分: 程序计数器(Progra ...
随机推荐
- Oracle删除步骤
1.Oracle卸载要求比较严格,不能简单的卸载就完事了:当然Oracle卸载也没有那么难,只是步骤比较多.Oracle10g还是Oracle11g卸载步骤都是一样的.下边详细介绍一下. 找到Orac ...
- spring boot 基础篇 -- 阿里多数据源
这块是比较基础的配置,阿里数据库配置还是比较好用的,并且可以用来监控数据源的情况.废话不多说,下面看代码. 基于maven项目,在pom.xml中添加引用: <dependency> &l ...
- hzau 1209 Deadline(贪心)
K.Deadline There are N bugs to be repaired and some engineers whose abilities are roughly equal. And ...
- SSM整合(spring、springMVC、mybatis)
需要用的包: 包括:spring的包.springMVC的包.mybatis的包.数据库驱动包.json相关的包 配置如下,首先是mybatis的配置 <?xml version="1 ...
- Linux下添加,删除,修改,查看用户和用户组
linux下添加,删除,修改,查看用户和用户组 1,创建组 groupadd test 增加一个test组 2,修改组 groupmod -n test2 test 将test组的名子改成test ...
- HDU - 5126 stars (CDQ分治)
题目链接 题目大意:一共有Q(1<=Q<=50000)组操作,操作分为两种: 1.在x,y,z处添加一颗星星 2.询问以(x1,y1,z1)与(x2,y2,z2)为左上和右下顶点的矩形之间 ...
- [Luogu2371][国家集训队]墨墨的等式
luogu 题意 给出\(n,a_i,B_{min},B_{max}\),求使得\(a_1x_1+a_2x_2+...+a_nx_n=B\)存在一组非负整数解的\(B\in[B_{min},B_{ma ...
- VS2005环境下的DLL应用
VS2005环境下的DLL应用 作者:一点一滴的Beer http://beer.cnblogs.com/ 以前写过一篇题为<VC++的DLL应用(含Demo演示)>的文章,当时是刚开始接 ...
- /etc/ntp.conf
摘录一: System:ubuntu10.04 配置文件路径:/etc/ntp.conf 配置格式:关键字(如server) 参数(如prefer) 以换行为结束,所以一个配置不能占多行. ...
- 基于JDK1.7.0_80与JDK1.8.0_66做的分析
JDK1.7中 使用一个Entry数组来存储数据,用key的hashcode取模来决定key会被放到数组里的位置,如果hashcode相同,或者hashcode取模后的结果相同(hash collis ...