优化长寿命对象的集合

Jay*_*Jay 3 c# optimization garbage-collection

背景:我有一项服务,其目的是为请求者提供对象 - 它基本上从数据库中获取复杂数据并将其转换一次(有点像数据视图)以生成简化记录.然后,它根据需要提供多达10万条记录(取决于请求的性质),从而为其他服务的请求提供服务.

这个想法是复杂的转换只进行一次并由服务缓存 - 它比每次访问视图时让数据库更好地工作更快,并且为了我的目的工作得很好.(我相信这被称为SSOS)

缓存数据的方式是在对象列表中,这些对象是标准.Net类型的属性包.这些对象没有引用任何其他内容.记录将定期更改,并且必须更新缓存,这意味着必须定位,丢弃和替换原始记录.

现在缓存中的记录将在那里存在很长时间,并且将被标记为Gen 2集合; 几乎所有的收藏品都会在Gen2阶段发生,因为这些物品长期存在(故意).

所以我对Gen2集合的理解是它们很慢,如果集合主要在Gen2上运行,那么优化器会更频繁地这样做.

我希望能够以一种最终不会触发完整Gen2集合的方式取消引用列表中的对象......我在想,也许有一种方法可以将它标记为Gen0然后de-在替换它之前引用它 - 但我认为这不可行.

我仅限于使用.Net 4,该应用程序是一项服务,为多达100个客户提供数据,这些客户在一段时间内请求完整列表或更改列表.

问题:任何人都可以提出一种以GC友好的方式取消引用长寿命对象的方法,或者可能采用另一种方法来解决这个问题吗?

Mar*_*ell 7

对此没有简单的答案.如果你有很多长寿命的物品,那么正如我在这里讨论的那样,完整的藏品确实会受到伤害.既然一张图片说了千言万语:

在此输入图像描述

那些垂直尖峰是垃圾收集发生的地方并且屠杀响应时间.

我们减少这种影响的方式是:没有大量长寿的物体.我们所做的是将类更改为structs,这意味着唯一的对象是包含它们的数组.我们幸运的是,数据很简单并且不涉及strings,当然它们本身就是对象.我们还做了一些疯狂的固定大小缓冲工作来减少以前收集的东西,并改变了对索引的引用(进入数组).如果你必须使用数据,也许尽量确保您不会有20,000个警报的不同与相同的值instancs -某种手工interner的(一个就足够了),可以真正有用的存在.string stringDictionary<string,string>

请注意,这不会影响您的公共 API,因为您始终可以classstruct存储中创建旧数据- 不同之处在于它class仅作为DTO短暂存在 - 因此将在下一代gen-0扫描中以低成本收集.

YMMV,但这对我们来说效果很好.

问题是:在使用s 时你需要非常小心struct; 我强烈建议让它们一成不变.