有关如何编写静态分析规则 (FXCop) 以确保删除事件委托的任何想法

发布于 2024-07-19 08:53:11 字数 261 浏览 6 评论 0原文

我们一直在进行大量的内存泄漏分析,发现影响因素之一是未删除事件上的委托,导致对象无法足够快地被 GC(有时甚至永远)。

有人知道如何在 FXCop 中编写规则以确保我们将委托从处理程序中删除吗?

我刚刚看到这个,因此我会在那里问了解更多信息。

We have been going through a big memory leak analysis and have found one of the contributing factors has been the non removal of delegates on events causing objects to not be GCed quickly enough (or sometimes forever).

Would anyone have any ideas as to how to write a rule in FXCop to ensure that we have delegates are removed from handlers?

I've just seen this and as such I'll ask there for more information.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

沧笙踏歌 2024-07-26 08:53:11

你需要更具体。 您不需要检查所有事件委托是否已取消订阅,因为在常见情况下,订阅者的寿命比发布者短。 仅当您的订阅者比发布者寿命更长时才会发生内存泄漏,因此存在引用,这会阻止 GC 收集发布者对象。

现在我们需要验证,如果您订阅了相对较短生命周期的对象上的事件,您最终会取消订阅它。

在这种情况下,我可以提出一个启发式方法:分析所有局部变量对象(由当前代码块 {} 限定范围)以及您显式 Dispose 的所有对象。 对于这些对象上的每个事件,都会计算您订阅它们的次数和取消订阅的次数。 如果第一个数字更大,则发出警告。

当然,这并不能涵盖所有情况,但我想没有静态方法可以涵盖这个问题中的所有情况,您需要一些足够好的方法。

我不会在这里提及动态分析和代码审查的优点,因为它是一个单独的主题,与问题无关。

You need to be more specific. You don't need to check that ALL event delegates were unsubscribed, because in a common case a subscriber lives shorter life than a publisher. And a memory leak only happens when your subscriber appears to be longer-lived than a publisher, hence there is a reference, which prevent GC from collecting the publisher object.

Now we need to verify that if you subscribe to an event on a relatively short-living object, you unsubscribe from it eventually.

An heuristics I can come up with in this case: analyze all local-variable objects (that are scoped by the current code block {}) and all objects, which you explicitly Dispose. For every event on these objects count the number of times you subscribe to them and the number of times you unsubscribe. If the first number is greater then emit a warning.

Of course that doesn't cover all the cases, but I guess no static approach can cover all the cases in this problem, you need some method that is good enough.

I won't mention the advantages of dynamic analysis and code reviews here as it is a separate topic, not related to the question.

×眷恋的温暖 2024-07-26 08:53:11

好的,除了实现实际检查的问题之外(在我看来,这与路径覆盖率非常相似 因此不实用) - 这是编写新的 FxCop 规则的方法:

首先,一些文章对我有过一次帮助:

实施一个简单的规则是没什么大不了。 在您的项目中,您需要一个 Rules.xml 文件作为嵌入资源(请参阅此处)。 您从 BaseIntrospectionRule 派生您的类,并将代码添加到 Check() 方法中:

public override ProblemCollection Check( TypeNode typeNode )
{
  if( type.IsPublic )
  {
    Problems.Add( new Problem( ... ) );
  }
  return Problems;
}

我以前曾这样做过。 我希望它仍然像描述的那样工作:)

Ok, beside the problem of implementing the actual check (in my opinion this is very similar to a path coverage and thus not practical) - here is the way to write a new FxCop rule it:

At first some articles that helped me once:

Implementing a simple rule is no big deal. In your project you need a Rules.xml file as an embedded resource (see here). You derive your class from BaseIntrospectionRule and add your code to the Check()-method:

public override ProblemCollection Check( TypeNode typeNode )
{
  if( type.IsPublic )
  {
    Problems.Add( new Problem( ... ) );
  }
  return Problems;
}

I did this some times ago. I hope it still works as described :)

水溶 2024-07-26 08:53:11

您能否强制规定所有事件订阅都应通过 WeakReferences 处理? 我认为这应该比分析程序的实际流程更容易实现。

Can you force a rule that all event subscriptions should be handled through WeakReferences? I'm thinking this should be easier to implement than having to analyze the actual flow of your program.

茶花眉 2024-07-26 08:53:11

假设实现处理程序的对象以某种方式引用回带有事件的对象是否安全? 如果是这种情况,你最好想办法以另一种方式打破这个循环。

不久前,我们在 ASP.NET 页面上的事件处理程序中也遇到过类似的情况。 实现处理程序的对象也具有对页面的引用。 在从架构上破坏了尽可能多的链接后,剩下的一些链接被更改为弱引用。 不再有记忆问题!

Is it safe to assume the objects implementing the handlers somehow have references back to the object with the events? If that's the case you're better off figuring out how to break the cycle another way.

We had something similar going on a while back with event handlers on ASP.NET pages. The objects that implemented the handlers also had references to the pages. After breaking as many of the links architectually as we could, the few left-overs were changed to WeakReferences. No more memory problems!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文