登录
注册
开源
企业版
高校版
搜索
帮助中心
使用条款
关于我们
开源
企业版
高校版
私有云
模力方舟
AI 队友
登录
注册
12月21日就在北京,来看大模型推理 + 国产硬件生态 + 开源社区分享,一起搞技术、聊开源、领福利~~
代码拉取完成,页面将自动刷新
捐赠
捐赠前请先登录
取消
前往登录
扫描微信二维码支付
取消
支付完成
支付提示
将跳转至支付宝完成支付
确定
取消
Watch
不关注
关注所有动态
仅关注版本发行动态
关注但不提醒动态
3
Star
45
Fork
21
DreamCoders
/
CoderGuide
代码
Issues
1169
Pull Requests
0
Wiki
统计
流水线
服务
JavaDoc
PHPDoc
质量分析
Jenkins for Gitee
腾讯云托管
腾讯云 Serverless
悬镜安全
阿里云 SAE
Codeblitz
SBOM
我知道了,不再自动展开
更新失败,请稍后重试!
移除标识
内容风险标识
本任务被
标识为内容中包含有代码安全 Bug 、隐私泄露等敏感信息,仓库外成员不可访问
V8 的内存分代和回收算法请简单讲一讲
待办的
#IAG9KR
陌生人
拥有者
创建于
2024-07-29 16:04
<p style="text-align: start;">在V8中会把堆分为新生代和<a href="https://www.zhihu.com/search?q=%E8%80%81%E7%94%9F%E4%BB%A3&search_source=Entity&hybrid_search_source=Entity&hybrid_search_extra=%7B%22sourceType%22%3A%22article%22%2C%22sourceId%22%3A%22417023073%22%7D" target="">老生代</a>两个区域</p><p style="text-align: start;">V8实现了GC算法,采用了分代式垃圾回收机制,所以V8将堆内存分为<span style="background-color: rgb(248, 248, 250);"><code>新生代</code></span>(副垃圾回收器)和<span style="background-color: rgb(248, 248, 250);"><code>老生代</code></span>(主垃圾回收器)两个部分</p><h4 style="text-align: start; line-height: 1.5;"><strong>新生代</strong></h4><p style="text-align: start;">新生代中通常只支持1~8M的容量,所以主要<strong>存放生存时间较短的对象</strong></p><p style="text-align: start;">新生代中使用<span style="background-color: rgb(248, 248, 250);"><code>Scavenge GC</code></span>算法,将新生代空间分为两个区域:对象区域和空闲区域。</p><p style="text-align: start;">顾名思义,就是说这两块空间只使用一个,另一个是空闲的。工作流程是这样的</p><ul><li style="text-align: start;">将新分配的对象存入对象区域中,当对象区域存满了,就会启动GC算法</li><li style="text-align: start;">对对象区域内的垃圾做标记,标记完成之后将对象区域中还存活的对象复制到空闲区域中,已经不用的对象就销毁。这个过程不会留下内存碎片</li><li style="text-align: start;">复制完成后,再将对象区域和空闲互换。既回收了垃圾也能让新生代中这两块区域无限重复使用下去</li></ul><p style="text-align: start;">正因为新生代中空间不大,所以就容易出现被塞满的情况,所以</p><ul><li style="text-align: start;"><strong>经历过两次垃圾回收依然还存活的对象会被移到老生代空间中</strong></li><li style="text-align: start;"><strong>如果空闲空间对象的占比超过25%,为了不影响内存分配,就会将对象转移到老生代空间</strong></li></ul><h4 style="text-align: start; line-height: 1.5;"><strong>老生代</strong></h4><p style="text-align: start;">老生代特点就是<strong>占用空间大</strong>,所以主要<strong>存放存活时间长的对象</strong></p><p style="text-align: start;">老生代中使用<span style="background-color: rgb(248, 248, 250);"><code>标记清除算法</code></span>和<span style="background-color: rgb(248, 248, 250);"><code>标记压缩算法</code></span>。因为如果也采用Scavenge GC算法的话,复制大对象就比较花时间了</p><h4 style="text-align: start; line-height: 1.5;"><strong>标记清除</strong></h4><p style="text-align: start;">标记清除的流程是这样的</p><ul><li style="text-align: start;">从根部(js的全局对象)出发,遍历堆中所有对象,然后标记存活的对象</li><li style="text-align: start;">标记完成后,销毁没有被标记的对象</li></ul><p style="text-align: start;">由于垃圾回收阶段,会暂停JS脚本执行,等垃圾回收完毕后再恢复JS执行,这种行为称为<span style="background-color: rgb(248, 248, 250);"><code>全停顿(stop-the-world)</code></span><br>比如堆中数据超过1G,那一次完整的垃圾回收可能需要1秒以上,这期间是会暂停JS线程执行的,这就导致页面性能和响应能力下降</p><p style="text-align: start;"><strong>增量标记</strong><br>所以在2011年,V8从 stop-the-world 标记切换到<span style="background-color: rgb(248, 248, 250);"><code>增量标记</code></span>。使用增量标记算法,GC 可以将回收任务分解成很多小任务,穿插在JS任务中间执行,这样避免了应用出现卡顿的情况</p><p style="text-align: start;"><strong>并发标记</strong><br>然后在2018年,GC 技术又有重大突破,就是<span style="background-color: rgb(248, 248, 250);"><code>并发标记</code></span>。<strong>让 GC 扫描和标记对象时,允许JS同时运行</strong></p><p style="text-align: start;"><strong>标记压缩</strong><br>清除后会造成堆内存出现内存碎片的情况,当碎片超过一定限制后会启动<span style="background-color: rgb(248, 248, 250);"><code>标记压缩算法</code></span>,将存活的对象向堆中的一端移动,到所有对象移动完成,就清理掉不需要的内存</p>
<p style="text-align: start;">在V8中会把堆分为新生代和<a href="https://www.zhihu.com/search?q=%E8%80%81%E7%94%9F%E4%BB%A3&search_source=Entity&hybrid_search_source=Entity&hybrid_search_extra=%7B%22sourceType%22%3A%22article%22%2C%22sourceId%22%3A%22417023073%22%7D" target="">老生代</a>两个区域</p><p style="text-align: start;">V8实现了GC算法,采用了分代式垃圾回收机制,所以V8将堆内存分为<span style="background-color: rgb(248, 248, 250);"><code>新生代</code></span>(副垃圾回收器)和<span style="background-color: rgb(248, 248, 250);"><code>老生代</code></span>(主垃圾回收器)两个部分</p><h4 style="text-align: start; line-height: 1.5;"><strong>新生代</strong></h4><p style="text-align: start;">新生代中通常只支持1~8M的容量,所以主要<strong>存放生存时间较短的对象</strong></p><p style="text-align: start;">新生代中使用<span style="background-color: rgb(248, 248, 250);"><code>Scavenge GC</code></span>算法,将新生代空间分为两个区域:对象区域和空闲区域。</p><p style="text-align: start;">顾名思义,就是说这两块空间只使用一个,另一个是空闲的。工作流程是这样的</p><ul><li style="text-align: start;">将新分配的对象存入对象区域中,当对象区域存满了,就会启动GC算法</li><li style="text-align: start;">对对象区域内的垃圾做标记,标记完成之后将对象区域中还存活的对象复制到空闲区域中,已经不用的对象就销毁。这个过程不会留下内存碎片</li><li style="text-align: start;">复制完成后,再将对象区域和空闲互换。既回收了垃圾也能让新生代中这两块区域无限重复使用下去</li></ul><p style="text-align: start;">正因为新生代中空间不大,所以就容易出现被塞满的情况,所以</p><ul><li style="text-align: start;"><strong>经历过两次垃圾回收依然还存活的对象会被移到老生代空间中</strong></li><li style="text-align: start;"><strong>如果空闲空间对象的占比超过25%,为了不影响内存分配,就会将对象转移到老生代空间</strong></li></ul><h4 style="text-align: start; line-height: 1.5;"><strong>老生代</strong></h4><p style="text-align: start;">老生代特点就是<strong>占用空间大</strong>,所以主要<strong>存放存活时间长的对象</strong></p><p style="text-align: start;">老生代中使用<span style="background-color: rgb(248, 248, 250);"><code>标记清除算法</code></span>和<span style="background-color: rgb(248, 248, 250);"><code>标记压缩算法</code></span>。因为如果也采用Scavenge GC算法的话,复制大对象就比较花时间了</p><h4 style="text-align: start; line-height: 1.5;"><strong>标记清除</strong></h4><p style="text-align: start;">标记清除的流程是这样的</p><ul><li style="text-align: start;">从根部(js的全局对象)出发,遍历堆中所有对象,然后标记存活的对象</li><li style="text-align: start;">标记完成后,销毁没有被标记的对象</li></ul><p style="text-align: start;">由于垃圾回收阶段,会暂停JS脚本执行,等垃圾回收完毕后再恢复JS执行,这种行为称为<span style="background-color: rgb(248, 248, 250);"><code>全停顿(stop-the-world)</code></span><br>比如堆中数据超过1G,那一次完整的垃圾回收可能需要1秒以上,这期间是会暂停JS线程执行的,这就导致页面性能和响应能力下降</p><p style="text-align: start;"><strong>增量标记</strong><br>所以在2011年,V8从 stop-the-world 标记切换到<span style="background-color: rgb(248, 248, 250);"><code>增量标记</code></span>。使用增量标记算法,GC 可以将回收任务分解成很多小任务,穿插在JS任务中间执行,这样避免了应用出现卡顿的情况</p><p style="text-align: start;"><strong>并发标记</strong><br>然后在2018年,GC 技术又有重大突破,就是<span style="background-color: rgb(248, 248, 250);"><code>并发标记</code></span>。<strong>让 GC 扫描和标记对象时,允许JS同时运行</strong></p><p style="text-align: start;"><strong>标记压缩</strong><br>清除后会造成堆内存出现内存碎片的情况,当碎片超过一定限制后会启动<span style="background-color: rgb(248, 248, 250);"><code>标记压缩算法</code></span>,将存活的对象向堆中的一端移动,到所有对象移动完成,就清理掉不需要的内存</p>
评论 (
0
)
登录
后才可以发表评论
状态
待办的
待办的
进行中
已完成
已关闭
负责人
未设置
标签
Node
未设置
标签管理
里程碑
未关联里程碑
未关联里程碑
Pull Requests
未关联
未关联
关联的 Pull Requests 被合并后可能会关闭此 issue
分支
未关联
未关联
master
开始日期   -   截止日期
-
置顶选项
不置顶
置顶等级:高
置顶等级:中
置顶等级:低
优先级
不指定
严重
主要
次要
不重要
参与者(1)
1
https://gitee.com/DreamCoders/CoderGuide.git
git@gitee.com:DreamCoders/CoderGuide.git
DreamCoders
CoderGuide
CoderGuide
点此查找更多帮助
搜索帮助
Git 命令在线学习
如何在 Gitee 导入 GitHub 仓库
Git 仓库基础操作
企业版和社区版功能对比
SSH 公钥设置
如何处理代码冲突
仓库体积过大,如何减小?
如何找回被删除的仓库数据
Gitee 产品配额说明
GitHub仓库快速导入Gitee及同步更新
什么是 Release(发行版)
将 PHP 项目自动发布到 packagist.org
评论
仓库举报
回到顶部
登录提示
该操作需登录 Gitee 帐号,请先登录后再操作。
立即登录
没有帐号,去注册