【问题标题】:c# find unused objects of specific class before garbage collectionc#在垃圾收集之前查找特定类的未使用对象
【发布时间】:2011-03-20 22:27:35
【问题描述】:

您好,非常感谢您的帮助!

有没有人知道在垃圾收集之前找到特定类的未引用对象? (最好尽快)

就我而言,我需要创建许多特定类的小对象,仅供临时使用。问题是我不知道何时不再需要该对象。我想在垃圾收集之前(尽快)收集该类的对象,以便我可以回收它们并且不需要创建新的对象。我认为这会使代码更快。

亲切的问候, 大卫

【问题讨论】:

  • 是什么让您认为如果您可以回收对象,您的代码会更快?我不认为我在 C# 中见过这样的案例。
  • 这些对象的初始化成本高吗?否则,您不太可能获得任何好处。
  • @Gabe:我正在开发一款游戏,该游戏将通过对某些对象使用对象池得到显着帮助。这些对象的生存时间相对较短,通常非常相似并且经常被创建。游泳池完全符合我的需要。哦,我已经完成了性能测量,知道游泳池会帮助我。 :)

标签: c# c#-4.0 garbage-collection


【解决方案1】:

首先,在您执行此操作之前,您应该进行广泛的分析以确定您确实确实存在由收集压力引起的性能问题。垃圾收集器经过高度调整,大部分时间都运行良好;出于性能原因需要池化对象的情况很少见。

在那种情况下,我实际上是 am;我们通过广泛的测试确定,我们一直在临时使用某些对象(本质上是其他对象的“构建器”),并且由于频繁重新分配它们而导致的收集压力成本是可衡量的并且很高。

我们所做的是我们有一个池类,它维护一个“空白”对象数组。当您需要一个新对象时,池会检查数组并返回数组中的一个对象(如果有的话),将数组条目清空。如果我们没有,那么它会创建一个新对象。当临时用户处理完该对象后,它会将其传回池中,该池将其“清空”并将其放回数组中。 (必要时增加数组。)

如果用户忘记将对象放回池中,或者因为在“返回池”调用之前抛出异常而无法这样做,谁在乎呢?在这种情况下,我们所做的一切可能只是对未来的分配进行了轻微的优化。代价是您需要记住在完成后将对象放回池中。

据我所知,没有办法“挂钩”垃圾收集器以自动将东西放回池中。

【讨论】:

  • 您是否使用IDisposable 将对象返回到它们的池中?
  • @Gabe:有趣的是,我们周四刚刚在我的团队中讨论了这个问题。我们决定不,使用 IDisposable 将对象移回池是不合适的。首先,IDisposable 应该用于 非托管 资源。其次,如果一个对象在异常情况下被 GC 回收,那么谁在乎呢?这种情况是例外的,程序可能无论如何都会异常终止。第三,如果一个对象在正常终止时没有被移回池中,那么我们有断言记录了这一事实,所以我们会抓住这个错误。
  • 我认为 IDisposable 对于任何需要确定性生命周期管理的东西都很有用,其中非托管资源只是最常见的。我认为 IObservable 是使用 IDisposable 的托管对象的最佳示例。在这种情况下,如果合适的话,我可能会选择实现 IDisposable 以启用 using 模式。
  • @Eric:我同意@Gabe,IDisposable 适用于任何应该具有确定性生命周期的东西。终结器用于非托管资源。 (当然,如果你有一个终结器,你应该有一个Dispose 方法)。但是ofsource,你不需要IDisposable;你总是可以自己写try-finally
  • 我知道我是少数人相信“使用”和 IDisposable 是为了礼貌地及早清理稀缺的非托管资源。我发现很遗憾我们将它用于运行迭代器的 finally 块。我也认为 RAII 是一个糟糕的想法。
【解决方案2】:

您不能直接控制垃圾回收,但您可以创建一个管理器类来负责创建、保存引用和处置这些对象。只要管理器类在范围内,它的对象就不会被垃圾回收。

【讨论】:

  • 可能我不够清楚,所以我再问:如何识别特定类的未使用(未引用)对象,以便知道何时回收它有意义?我不想回收可能仍在使用(或至少被引用)的对象。
  • 你想错了。这会自动发生。如果您不希望回收一个对象,请将对它的引用保留在范围内,并且不要调用 Dispose()。阅读using 声明,这可能会对您有所帮助:msdn.microsoft.com/en-us/library/yh598w02.aspx
  • 感谢您的帮助,但我认为我们有一点误会。我想将特定类的所有未使用(未引用)对象放在特殊的堆栈列表中。当我再次需要该类的对象时,我只需从堆栈列表中弹出一个并再次使用它。如果堆栈列表为空,那么我创建一个新对象。你对弱引用有什么看法?他们可以识别未使用(未引用)的对象吗?亲切的问候,大卫
  • 这些对象有什么作用?您似乎在尝试避免实例化新实例的成本……也许您正在寻找单例模式?
  • 是的,没错!我试图避免实例化的成本。就我而言,我不能使用单例模式,因为我需要多个实例(在某些情况下)。我听说垃圾收集器有一个未引用对象的列表,是否可以访问该列表?最佳解决方案是,每次相关对象之一变为未引用时都可以引发事件。
猜你喜欢
  • 2010-11-08
  • 1970-01-01
  • 2012-01-19
  • 2014-06-25
  • 1970-01-01
  • 2019-03-23
  • 2011-09-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多