V8垃圾回收
1.js
中的垃圾收集
优点:可以简化开发,节省代码
缺点:无法完整的掌握内存的分配与回收具体过程
1.1.带来的问题
1.2.V8内存管理
1.2.1.V8内存限制
- 在64位操作系统可以使用1.4G内存
- 在32位操作系统可以使用0.7G内存
1.2.2.V8内存管理
- JS对象都是通过V8进行分配管理内存的
process.memeoryUsage
返回一个对象,包含了Node进程的内存占用信息- rss(resident set size):所有内存占用,包括指令区和堆栈
- heapTotal:
堆
占用的内存,包括用到的和没用到的 - heapUsed:用到的堆的部分,判断内存泄漏,以
heapUsed
字段为准 - external:V8引擎内部的
C++
对象占用的内存
1.2.3.为何限制内存大小
- 因为v8的垃圾收集工作原理导致的,1.4G内存完全一次垃圾收集需要1秒以上
- 这个暂停时间成为
Stop The World
,在这个期间,应用的性能和响应能力都会下降
1.2.4.如何打开内存限制
- 一旦初始化成功,生效后不能再修改
-max-new-space-size
,最大new space
大小,执行scavenge
回收,默认16M,单位KB-max-old-space-size
最大old space
大小,执行markSweep
回收,默认1G,单位MB
2.V8垃圾回收机制
- V8是基于分代垃圾回收
- 不同代垃圾回收机制也不一样
- 按存活的时间分为新生代和老生代
2.1.分代
- 年龄小的是新生代,由From区域和To区域两个区域组成
- 在64位系统里,新生代内存32M,From区域和To区域各占用16M
- 在32位系统里,新生代内存16M,From区域和To区域各占用8M
- 年龄大的是老生代,默认情况下,
- 64位系统下老生代内存1400M
- 32位系统下老生代内存700M
2.2.引用计数
- 语言引擎有一张引用表,保存了内存里面所用的资源引用次数
- 如果一个值的引用次数是0,就表示这个值不再用到了,因此可以将这块内存释放
2.3.新生代垃圾回收
- 新生代区域一分为二,每个16M,一个使用,一个空闲
- 开始垃圾回收的时候,会检查FROM区域中的存活对象,如果还活着,拷贝到TO区域,完成后释放空间
- 完成后FROM和TO交换
- 新生代扫描的时候是一种广度优先的扫描策略
- 新生代空间小,存活对象少
- 当一个对象经历过多次的垃圾回收依然存活的时候,生存周期比较长的对象会被移动到老生代,这个移动过程称为晋升
- 经过5次以上的回收还存在
- TO的空间使用占比超过25%,或者超大对象
2.4.老生代
mark-sweep
(标记清除),mark-compact
(标记整理)- 老生代空间大,大部分都是活着的对象,GC耗时比较长
- 在GC期间无法响应,
STOP-THE-WORLD
- V8有一个优化方案,增量处理,把一个大暂停换成多个小暂停
INCREMENTAL_GC
2.4.1.mark-sweep
标记清除
- 标记活着的对象,随后清除在标记阶段没有标记的对象,只清理死亡对象
- 问题在于清除后会出现内存不连续的情况,这种内存碎片会对后续的内存分配产生影响
- 如果分配一个大对象,碎片空间无法分配
2.4.2.mark-compact
标记整理
- 标记死亡后会对对象进行整理,活着的对象向左移动,移动完成后直接清理掉边界外的内存
2.4.3.incremental marking
增量标记
- 增量标记就是把一口气的停顿拆分成了多个小步骤,做完一步程序运行一会儿,垃圾回收和应用程序运行交替进行,停顿时间可以减少到
1/6
左右,包括垃圾回收的占用时间
2.4.4.对比
回收算法 | Mark-Sweep | Mark-Compact | Scavenge | 速度 | 中等 | 最慢 | 最快 | 空间开销 | 少 | 少 | 双倍空间(无碎片) | 是否移动对象 | 否 | 是 | 是 |
---|
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!