|
| 1 | +# 内存占用 1G 调研报告 |
| 2 | + |
| 3 | +> 诊断 session `a3593062` RSS 达 1.09 GB,定位 Bun 运行时内存膨胀根因 |
| 4 | +
|
| 5 | +## 数据收集 |
| 6 | + |
| 7 | +- **诊断数据**: RSS 1,118 MB,V8 heap 84 MB,原生内存缺口 1,034 MB(92%) |
| 8 | +- **构建方式**: `bun run build:vite` → Vite/Rollup 单文件构建,产物 17MB `dist/cli.js` |
| 9 | +- **Vite 配置**: `codeSplitting: false`(`vite.config.ts:97`),所有代码内联为单文件 |
| 10 | +- **Node.js 对比**: 相同 17MB 产物,Node.js RSS 仅 223 MB(`--version`)/ 340 MB(完整加载) |
| 11 | + |
| 12 | +## 探索与验证 |
| 13 | + |
| 14 | +### 已确认 |
| 15 | + |
| 16 | +| 问题 | 位置 | 说明 | |
| 17 | +|------|------|------| |
| 18 | +| **根因: Vite 单文件构建 + Bun 解析大文件内存效率低** | `vite.config.ts:97` | `codeSplitting: false` 产出 17MB 单文件,Bun/JSC 解析时 RSS 暴涨至 966MB | |
| 19 | +| Node.js 对同等 17MB 文件仅需 223MB | 实测 | V8 对大文件解析的内存效率远优于 JSC | |
| 20 | +| Bun.build 代码分割可解决问题 | 实测 | `bun run build`(代码分割 → 627 chunk)Bun RSS 仅 30MB(`--version`)/ 318MB(完整加载) | |
| 21 | + |
| 22 | +### 已否认 |
| 23 | + |
| 24 | +- 不是 feature flags 数量问题 — 全部 35 features 开启时,代码分割构建内存正常 |
| 25 | +- 不是内存泄漏 — `detachedContexts: 0`,`activeHandles: 0` |
| 26 | +- 不是原生 addon 问题 — vendor 文件仅 2.7MB |
| 27 | +- 不是 TypeScript 源码体量问题 — `bun run dev`(直接加载 TS)完整路径仅 345MB |
| 28 | + |
| 29 | +## 结论 |
| 30 | + |
| 31 | +**根因是 Vite 构建配置 `codeSplitting: false`,产出 17MB 单文件,Bun/JSC 解析单文件大 JS 时内存效率极差(966MB vs Node 的 223MB)。** |
| 32 | + |
| 33 | +实测对比矩阵: |
| 34 | + |
| 35 | +| 构建方式 | 产物结构 | Bun RSS | Node RSS | Bun/Node | |
| 36 | +|----------|----------|---------|----------|----------| |
| 37 | +| `build:vite` | 17MB 单文件 | **966 MB** | 223 MB | 4.3x | |
| 38 | +| `build:vite` pipe mode | 同上 | **1,088 MB** | 340 MB | 3.2x | |
| 39 | +| `build` (Bun) | 627 chunk | 30 MB | 42 MB | 0.7x | |
| 40 | +| `build` (Bun) pipe mode | 同上 | 318 MB | 253 MB | 1.3x | |
| 41 | +| `bun run dev` TS 源码 | 动态加载 | 42 MB | — | — | |
| 42 | +| `bun run dev` pipe mode | 动态加载 | 345 MB | — | — | |
| 43 | + |
| 44 | +核心差异: |
| 45 | +- **Node/V8** 解析 17MB 文件只需 223MB — V8 的懒解析(lazy parsing)只编译入口需要的部分 |
| 46 | +- **Bun/JSC** 解析 17MB 文件需要 966MB — JSC 对单文件做全量编译,bytecode + JIT 占用大量原生内存 |
| 47 | +- 代码分割后(627 个小 chunk),Bun 按需加载,内存回到正常水平 |
| 48 | + |
| 49 | +## 建议 |
| 50 | + |
| 51 | +1. **开启 Vite 代码分割** — 在 `vite.config.ts` 中启用 `codeSplitting: true` 或使用 Rollup 的 `manualChunks` 配置。这是最直接的修复 |
| 52 | +2. **或切换到 Bun.build** — `bun run build` 已默认启用代码分割(`splitting: true`),Bun RSS 仅 30-318MB |
| 53 | +3. **如果必须单文件** — 考虑用 Node.js 运行 Vite 产物(`node dist/cli-node.js`),代价是失去 Bun 特有 API |
| 54 | +4. **验证 `codeSplitting: false` 的存在理由** — 注释说"all dynamic imports inlined",可能是为了简化部署。评估是否真的需要单文件 |
0 commit comments