#741·yjs

具有大量已删除的映射项 (tombstone) 的 ydocs 会泄露内存

作者: Xyz3R创建于 2025年10月21日更新于 2026年7月11日
标签bug

Hi! 我们有一些客户文档,其中包含大量删除的结构,大约为 10 万个。 尽管我承认这是很多,但这些文档的生命周期较长,而且不太大(约 200MB)。 当将这些文档加载到 node/bun/deno 中的 yjs 中时,会消耗更多的内存,而不在销毁文档并运行垃圾回收时释放。 我们还观察到,调用 `encodeStateAsUpdate` 时,消耗的内存量更大,虽然至少会被释放,但超出了合理的范围(75 倍文档大小)。 我准备了一个仓库,其中包含一个简单的重现案例和一些说明,请参阅:https://GitHub.com/Echometer-GmbH/yjs-large-file-leak 该仓库还包含了更详细的说明,说明如何运行它 - 这应该很容易做到! 我测试了 Bun 和 Deno 作为运行时 - 行为类似,但 Deno 在 OOM 发生时会崩溃,而 Bun 至少保持活动。 ** 对于由包含的脚本生成的测试文档的观察行为** 1. 文档加载使内存使用量飙升至大约 4GB(20 倍文档大小) 2. 调用 `encodeStateAsUpdate` 使内存使用量飙升至大约 15GB(约 75 倍文档大小)。 然而,似乎一旦运行完成,这块内存至少会被释放。 3. 执行 ydoc.destroy() 并强制垃圾回收器运行后,内存消耗保持在约 4GB。 ** 环境信息 ** - Node.js / Bun / Deno - 13.6.27 ** 额外上下文 ** 仓库中包含一个脚本,用于生成一个重现该问题的 ydoc。 该脚本生成一个 244MB 的文件,该文件在一段时间内将内存使用量提高到至少 16GB - 如果您没有那么多可用的内存,则可以编辑 `constants.ts` 中的 `bulkUpdaterRuns` 变量,将其设置为较小的值,然后按照仓库的 README.md 中的说明重新生成文件。