作者:李旭光
引用请标明出处
V8引擎如何回收垃圾
为什么我们要关注内存
- 防止页面占用内存过大,引起客户端卡顿,甚至无响应
- Node使用的也是v8,内存对于后端服务的性能至关重要。因为服务的持久性,后端更容易造成内存溢出
v8引擎的内存回收机制
v8的内存分配
新生代内存空间 - from
- to
老生代内存空间内存大小
- 和操作系统有关 — 64位(1.4G)32位(0.7G)
- 64位下 新生代(64MB) 老生代(1400MB)
- 32位下 新生代(16MB) 老生代(700MB)
为什么不占多一点内存
- js设计之初是为浏览器
- 前端特点 — 不持久化,执行一遍就回收了,所以1.4G够用了
- js回收内存会暂停执行代码
垃圾回收算法
新生代简单的说就是复制
- 新生代用来放新产生的变量,根据条件放到老生代,有用的放到to里(把有用的留一边,清空另一边,往复进行)
- 算法复杂度(时间复杂度,空间复杂度)—- 牺牲空间换时间
老生代就是标记、删除、整理
- 为什么要整理
- 数组是需要连续的空间
新生代如何晋升到老生代
- 变量是否经过回收,第二次回收放到老生代,第一次回收放到To
- To空间使用了25%,放到老生代
V8是如何处理变量的
1 | // 浏览器查看内存 |
变量处理
- 内存主要就是存储变量等数据的
- 局部变量当程序执行结束,且没有引用的时候就会随着消失 — 可以被回收但不是说会马上回收
- 全局对象会始终存活到程序运行结束
如何查看V8内存使用情况
如何注意内存使用
优化内存的技巧
- 尽量不要定义全局变量
- 全局变量记得手动销毁掉
- 不推荐开发时写delete – 支持有问题,严格模式有bug
- 赋值为 undefined/null undefined 是变量 null 是保留字
- 用匿名自执行函数变全局为局部
(function(){})()
- 尽量避免使用闭包 —- 错误的观点,ie5时代的问题 —- 尽量避免使用闭包引用
闭包
1 | function a(){ |
防止内存泄漏
- 滥用缓存
- 大内存量操作
所有的优化都可以用缓存来解决,缓存通常都在全局,缓存可以直接拿来用;
1 | var 20*1024*1024; |
- 不要用v8来缓存
- 一定要用要的话加锁
nodejs中读取大文件要用流的形式,不要用读文件到buffer
fs.readFile()
fs.createReadStream()
浏览器中,大文件上传记得切片
file.slice(0,1000)
file.slice(1000,2000)