针对已知寿命较长的对象进行 .NET 垃圾收集调整
我正在开发一个 .NET 应用程序,其中有一个用字典实现的非常大的缓存。我通过 TTL 和定期检查过期项目的收割机从缓存中删除内容。给定的通用 TTL 值将以小时为单位。考虑到这一点,当我将每个对象放入缓存时,我可以做些什么,这样我就不必每次想缓存某些东西几个小时时都经过 Gen0 和 Gen1 了?
编辑:我应该更好地说明我的问题。我了解 .NET 垃圾收集的工作原理,并且我知道它很擅长它的工作。我同意,在理想情况下,您会希望它完全按照设计的方式工作。但具体来说,我想知道是否有任何方法可以控制它在这种情况下的工作方式。
I'm working in a .NET application where we have a very large cache implemented with a Dictionary. I remove things from the cache via a TTL and a reaper that periodically checks for expired items. A given common TTL value will be on the order of hours. Considering this, is there anything I can do each object as I put it into cache so that I don't have to go through Gen0 and Gen1 each time I want to cache something for hours?
EDIT: I should specify my question better. I understand how .NET garbage collection works and I know it's good at it's job. I agree that in ideal situations, you would want it work work exactly as it was designed. Specifically though, I'd like to know if there is any way to have control over how it works for this exact scenario.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您的对象将相对较快地升级到 Gen2,因为您的字典将始终将其保留为根。
没有一个 API 可以让您直接分配到不同的一代,但我怀疑这会对性能产生实际影响,因为如果对象保持固定状态,那么它们实际上不需要很长时间就会得到提升。任何具有多个小时生命周期的对象的缓存都不应该是经常分配的缓存,因此即使这是可能的,您所获得的节省也是微不足道的。
Your object will promote into Gen2 relatively quickly since your Dictionary will always leave it rooted.
There isn't an API that lets you allocate directly into a different generation, but I doubt that this will have a real-world impact on performance, since it really doesn't take long for objects to get promoted if they're staying rooted. Any cache with objects that have multi-hour lifetimes shouldn't be ones that are being allocated frequently, so the savings you'd receive even if this were possible would be trivial.
如果缓存很大,您可能需要考虑将对象集中到缓存中,而不是在一段时间后删除它们并放入新的对象。否则,您所做的就是从已塞入的对象中制造垃圾进入 Gen 2 的角落,GC 可能很长时间都抽不出时间来收集。这可能会导致应用程序的内存占用量增加,这是由未使用但也不会被收集的对象引起的,直到 GC 承受足够的压力以保证将它们挖出来为止。
显然,这与长时间运行此实例的场景更相关,但如果您在几个小时后扔掉东西,听起来就像您正在做的那样。
If the cache is large, you may want to look at pooling the objects in the cache, instead of getting rid of them after a time and putting new ones in. Otherwise what you're doing is making garbage out of objects that have been tucked into a corner of Gen 2, and which the GC may not get around to collecting for a long time. This can lead to an increased memory footprint for the application, caused by objects which are not in use but also not being collected until the GC is put under enough stress to warrant digging them out.
Obviously this is more relevant to the scenario of running this instance for a long time, but if you're throwing things away after a few hours, it sounds like that's what you're doing.