跳转至

V8 堆的内存布局

这篇只保留调试和漏洞分析最常用的结论,重点是把“空间职责”和“对象流转路径”看清楚。


一张图先看懂

这是面向调试/分析的常用视角,不是源码里的完整枚举(不同版本会有更多细分空间)。

V8 Heap (常用视角)
├─ New Space(年轻代)
│  ├─ From-Space
│  └─ To-Space
├─ Old Space(老年代)
├─ Large Object Spaces(大对象)
│  ├─ Old Large Object Space
│  └─ Code Large Object Space
├─ Code Space(代码对象)
└─ Read-Only Space(只读共享对象)

各空间做什么

空间 主要放什么 调试时最关心什么
New Space 新创建、短生命周期对象 Minor GC 频繁、对象会复制和搬移
Old Space 存活时间长的普通对象 进入老年代后回收策略和地址稳定性变化
Large Object Spaces 体积大的对象/代码对象 大对象通常不走半空间复制路径
Code Space JIT 代码与代码元数据 与普通 JS 对象分配路径不同
Read-Only Space 共享且不可变的内部对象 语义上是稳定区,不按普通可变对象处理

对象怎么流动(最常见路径)

new object
  -> New Space
      -> 死亡:Minor GC 回收
      -> 存活:晋升到 Old Space

large object
  -> 直接进入 Large Object Spaces

code object
  -> Code Space / Code Large Object Space

这也是为什么做 root cause 时,先分清对象属于哪个空间会很关键:它直接影响对象是否容易搬移、何时被回收、以及地址观察是否稳定。


Pointer Compression 不是堆空间

Pointer Compression 解决的是 值表示(tagged pointer/smi)的内存开销问题,不是“再新增一个 heap space”。
它影响字段里值怎么编码,不改变对象归属到哪个空间。

可配合阅读:V8 指针压缩机制


参考