为什么要关注内存:
1、防止页面占用内存过大,引起客户端卡顿,甚至无响应
2、Node使用的也是V8,内存对于后端服务的性能至关重要。因为服务的持久性,够短更容易造成内存溢出。
3、面试装逼神器(哈哈哈)
v8引擎内存回收机制
一、v8引擎内存分配
分为:新生代内存空间,老生代内存空间
内存大小:
和操作系统有关,64位为1.4G,32位为0.7G;64位下新生代的空间为64M,老生代为1400M;32位下新生代为16M,老生代为700M。
为什么是1.4G呢?
1、js最初设计是在浏览器上跑的,浏览器上的js不持久,1.4G安全够用,
2、js回收垃圾的时候,会暂停所有代码的执行,如果内存过大,回收时占用的时间会更多,300mb 回收 0.5秒
为什么新生代内存空间划分成两块呢(一个from,一个to)?
先说一下垃圾回收算法:
新生代回收算法简单的说就是复制:
老生代回收算法就是标记删除整理:
通过node来查看内存使用情况:process.memoryUsage();
{
rss: 22347776, //v8申请到的总占用空间
heapTotal: 9682944, //堆总内存
heapUsed: 5401712, //已经使用了的内存
external: 16901 // node底层是C++,他可以申请到一些C++的内存
}
通过浏览器来查看内存:
F12调试工具查看;performance
控制台输入:window.performance // 可以查看到当前页面的各种内存情况
function getmem(){
var mem = process.memoryUsage();
var format = function(bytes) {
return (bytes/1024/1024).toFixed(2) + ‘MB‘;
};
console.log(‘Process: heapTotal ‘ + format(mem.heapTotal) + ‘ heapUsed ‘ + format(mem.heapUsed) + ‘ rss ‘ + format(mem.rss));
};
2、内存处理
内存主要就是存储变量等数据结构的
局部变量当程序执行结束,并且引用的时候就会随着消失
全局对象会始终存货到程序运行结束
// 局部变量没有引用之后会被销毁
// 没有返回值,函数调用完了变量就会被销毁了
var size = 20*1024*1024;
function a(){
var arr1 = new Array(size);
var arr2 = new Array(size);
var arr3 = new Array(size);
var arr4 = new Array(size);
var arr5 = new Array(size);
var arr6 = new Array(size);
var arr7 = new Array(size);
var arr8 = new Array(size);
// var arr9 = new Array(size);
// return [arr1,arr2,arr3,arr4,arr5,arr6,arr7,arr8];
}
a();
getmem(); // Process: heapTotal 1288.83MB heapUsed 1283.34MB rss 1299.79MB
var arr9 = new Array(size);
// 有返回值的函数
var size = 20*1024*1024;
function a(){
var arr1 = new Array(size);
var arr2 = new Array(size);
var arr3 = new Array(size);
var arr4 = new Array(size);
var arr5 = new Array(size);
var arr6 = new Array(size);
var arr7 = new Array(size);
var arr8 = new Array(size);
// var arr9 = new Array(size);
return [arr1,arr2,arr3,arr4,arr5,arr6,arr7,arr8];
}
a();
getmem(); // Process: heapTotal 1288.83MB heapUsed 1283.34MB rss 1299.76MB
var arr9 = new Array(size);
// 函数只是return 了一个值,最后的执行结果与第一种情况没很大的差别
// 当将返回值赋值给一个变量后,变量保留了这一系列数组的引用,最后崩了
// var c = a();
三、如何注意内存的使用
1、优化内存的技巧:
尽量不要定义全局变量
全局变量要记得销毁掉
用匿名自执行函数变全局为局部
尽量避免闭包 --- 错误的????(闭包不会影响内存了)
// 全是全局变量
// 全局变量记得要销毁:delete arr (不推荐使用,在严格模式下回出现很多问题);
// arr1 =undefined; arr1 = null;
var size = 20*1024*1024; var arr1 = new Array(size); var arr2 = new Array(size); var arr3 = new Array(size); var arr4 = new Array(size); var arr5 = new Array(size); var arr6 = new Array(size); var arr7 = new Array(size); var arr8 = new Array(size);
arr1 = null; // 定义9之前吧1释放掉,也不会报错了
var arr9 = new Array(size);
getmem(); // 运行结果:Process: heapTotal 1288.83MB heapUsed 1283.34MB rss 1299.75MB // 当有9个时,会报内存泄漏错误
var size = 20*1024*1024;
// 用匿名自执行函数包裹起来,让整个代码编程局部的
// (function(){
// })();
(function(){var arr1 = new Array(size)})();
// 闭包???
for(var i=10000;i<10100;i++){
setTimeout(function(){
console.log(i);
getmem();
})
}
// 运行结果:
// 10100
// Process: heapTotal 6.73MB heapUsed 4.12MB rss 19.32MB
// 10100
// Process: heapTotal 9.73MB heapUsed 3.94MB rss 19.70MB
// 10100
for(var i=10000;i<10100;i++){
(function(i){
setTimeout(function(){
console.log(i);
getmem();
})
})(i)
}
// 运行结果:
// 10000
// Process: heapTotal 9.73MB heapUsed 3.94MB rss 19.72MB
// 10001
// Process: heapTotal 9.73MB heapUsed 3.95MB rss 19.75MB
// 10002
// Process: heapTotal 9.73MB heapUsed 3.95MB rss 19.75MB
// 两种方式的结果相差无几
// v8引擎,闭包基本不会影响内存了
2、防止内存泄漏
滥用内存
// node 服务是持久化的,
var http = require(‘http‘);
global.a = [];
var size = 20*1024*1024;
// 创建一个服务
http.createServer((req,res) => {
function getmem(){
var mem = process.memoryUsage();
var format = function(bytes) {
return (bytes/1024/1024).toFixed(2) + ‘MB‘;
};
console.log(‘Process: heapTotal ‘ + format(mem.heapTotal) + ‘ heapUsed ‘ + format(mem.heapUsed) + ‘ rss ‘ + format(mem.rss));
};
// 每一次请求服务都会往a里面push一个数组,
a.push(new Array(size));
getmem();
res.end(‘hello world‘);
}).listen(3000);
// 每刷新一次,内存占用情况就会变化一次
// 运行结果:
Process: heapTotal 169.75MB heapUsed 164.44MB rss 180.45MB
Process: heapTotal 329.76MB heapUsed 324.59MB rss 340.71MB
Process: heapTotal 490.27MB heapUsed 484.00MB rss 500.91MB
Process: heapTotal 650.28MB heapUsed 644.06MB rss 661.03MB
Process: heapTotal 810.29MB heapUsed 804.00MB rss 821.28MB
Process: heapTotal 970.30MB heapUsed 964.01MB rss 981.30MB
Process: heapTotal 1130.32MB heapUsed 1124.03MB rss 921.40MB
Process: heapTotal 1290.33MB heapUsed 1284.02MB rss 1287.71MB
再来一次就宕机了
// 所以后端特别关注内存
// 每一次请求服务都会往a里面push一个数组,
// 为了保证内存不泄露,在push之前,可以加一道锁,判断,当a的长度大于4时,就将第一个元素移除
if(a.length > 4){
a.shift();
}
大内存量操作
分片、断点
<input type=‘file‘ />
readfile() ,createReadStream,避免一次性读取过大的文件(避免一次性超大内存操作)
原文:https://www.cnblogs.com/1220x/p/11705141.html