我在 Unity 的Boehm–Demers–Weiser 垃圾收集器上运行,它是一种非分代 GC。
我在内存中有一大棵托管对象树(~100k 个对象,~200MiB 分配)。
这些对象本质上是一个缓存并且永远不会超出范围,因此它们实际上永远不会被 GC 清除。
然而,因为 Boehm 是非代际的,所以这个陈旧的缓存永远不会被提升到更高的代。这会导致标记阶段花费大量的处理时间,因为它必须在每个集合上遍历整个缓存,从而导致明显的延迟峰值。
正如 Unity 文档所说,这是“设计使然” :
至关重要的是,Unity 的垃圾收集(使用 Boehm GC 算法)是非分代和非压缩的。“非分代”意味着 GC 在执行收集过程时必须扫描整个堆,因此其性能会随着堆的扩展而下降。
我很清楚减少重复性垃圾分配的方法,但是我找不到有关如何在非分代 GC 中优化大型、陈旧的基线分配的任何信息。
进一步来说:
- 有没有办法将根指针(例如静态字段)标记为完全被 GC 忽略?
- 在标记阶段是否有一些数据结构模式可以更快地遍历?
- 相反,是否存在阻碍标记阶段速度的已知数据结构模式?
这些问题只是我解决这个问题的一些假设,但我愿意接受所有建议。