【问题标题】:.NET Garbage Collection Tuning for Objects Known to Have a Long Life.NET 垃圾收集调整已知具有较长生命周期的对象
【发布时间】:2011-05-27 04:32:05
【问题描述】:

我正在一个 .NET 应用程序中工作,其中我们有一个使用字典实现的非常大的缓存。我通过 TTL 和定期检查过期项目的收割机从缓存中删除内容。一个给定的通用 TTL 值将是几小时的数量级。考虑到这一点,当我将每个对象放入缓存时,我可以做些什么,这样我每次想要缓存几个小时的东西时就不必经过 Gen0 和 Gen1?

编辑:我应该更好地说明我的问题。我了解 .NET 垃圾收集的工作原理,并且我知道它擅长它的工作。我同意在理想情况下,您会希望它完全按照设计工作。但具体来说,我想知道是否有任何方法可以控制它在这种确切情况下的工作方式。

【问题讨论】:

  • 为什么需要调整它?您能描述一下您在垃圾收集方面遇到的确切问题吗?
  • +1 同意。由于对象是长期的,它们会被提升,这就是 GC 的设计方式。
  • 同意。我自己并不太关注垃圾收集,但这对我来说是一种尖叫的“过早优化”。
  • @0xA3 - 似乎如果您知道一个对象将是长寿的,那么您根本不希望它出现在 Gen0 或 Gen1 中。这样做意味着(在一段时间内)GC 将在不需要时检查它。 .NET 中的 GC 算法意味着一个对象通过 Gen0 和 Gen1 集合“证明”它是长寿的。就我而言,直接进入 Gen2 似乎是一个优势。
  • @Daniel - 这当然不是为时过早。我正在尝试优化存在内存问题和处理器上的高 GC 使用率的现有系统。

标签: .net garbage-collection


【解决方案1】:

您的对象将相对较快地升级为 Gen2,因为您的 Dictionary 将始终保持它为根。

没有一个 API 可以让您直接分配到不同的代,但我怀疑这会对性能产生实际影响,因为如果对象被提升确实不需要很长时间重新扎根。任何具有多小时生命周期的对象的缓存都不应该是那些被频繁分配的缓存,因此即使有可能,您所获得的节省也将是微不足道的。

【讨论】:

    【解决方案2】:

    如果缓存很大,您可能希望考虑将缓存中的对象池化,而不是在一段时间后将它们删除并放入新的对象。否则您所做的就是将这些对象变成垃圾已被塞进第 2 代的一个角落,GC 可能很长时间都无法收集。这可能会导致应用程序的内存占用增加,这是由未使用的对象引起的,但在 GC 承受足够的压力以保证将其挖掘出来之前也不会被收集。

    显然这与长时间运行此实例的场景更相关,但如果您在几个小时后扔掉东西,听起来就像您正在做的那样。

    【讨论】:

    • 您能否详细说明池化对象的含义?
    • 不是分配新对象并将它们放入缓存中,而是在进程开始时预先分配适当数量的缓存对象,并根据您希望它们缓存不同的内容更改这些对象的值时间。因此,您不会丢弃对象,只需在需要缓存新内容时更改它们的值。这是一个总体概述,但您可以在 en.wikipedia.org/wiki/Object_pool_pattern 找到更长的描述。这个想法是你停止分配/垃圾收集搅动 - 池对象永远不会死,所以 GC 不受池的影响。
    猜你喜欢
    • 2018-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-12
    • 2010-11-08
    相关资源
    最近更新 更多