我正在运行Unity的Boehm–Demers–Weiser garbage collector,这是一个非世代的GC。
我在内存中有一棵大的托管对象树(〜100k对象,〜200MiB分配)。
这些对象本质上是一个缓存,并且永远不会超出范围,因此它们实际上不会被GC清除。
但是,由于Boehm是非世代的,因此该陈旧的缓存永远不会移到更高的世代。这导致标记阶段要花费非常多的处理时间,因为它必须遍历每个集合的整个缓存,从而导致明显的滞后尖峰。
这是“故意设计的”,as the Unity documentation puts it:
至关重要的是,使用Boehm GC算法的Unity的垃圾收集是非世代且紧凑的。 “非世代”意味着GC在执行收集过程时必须扫过整个堆,因此其性能会随着堆的扩展而降低。
我很清楚减少重复发生的垃圾分配的方法,但是我找不到有关如何优化非世代GC中大型,陈旧的基准分配的任何信息。
更具体地说:
这些问题只是我为解决这一问题的一些假设,但我愿意接受所有建议。
答案 0 :(得分:0)
通过将程序启动与静态数据结构的初始化与稳态操作分开,可以近似生成代行为。可以忽略进入启动内存区域的所有指针,但不应忽略来自该指针的指针,因为尚未分配在切换点之后(由GC控制)的任何内容。
在切换到新区域之前,甚至可以对启动区域进行一次GC。从本质上讲,您最终将获得有限形式的基于区域的固定收集器,其中区域之间的引用仅在一个方向上发生。