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 指针压缩机制