IDisposable:内存泄漏

发布于 2024-12-14 09:05:47 字数 1048 浏览 1 评论 0原文

我目前正在审查一个 C# 应用程序,在其中我看到:

public static bool ServiceExists(string servicename)
{
    ServiceController[] services = ServiceController.GetServices();
    foreach (ServiceController s in services)
    {
        if (s.ServiceName == servicename)
        {
            return true;
        }
    }
    return false;
}

在此 回答,Henk说不使用Dispose()(或using)不会生成内存泄漏,是真是假?

我可以保留以前的代码吗?或者我应该写一些类似的内容:

public static bool ServiceExists(string servicename)
{
    ServiceController[] services = ServiceController.GetServices();
    bool exists = false;

    foreach (ServiceController s in services)
    {
        using(s)
        {
            if (s.ServiceName == servicename)
            {
                exists = true;
            }
        }
    }

    return exists;
}

在这种情况下不使用 Dispose() (或 using)有什么风险?

I'm currently do a review of a C# app in which I see that :

public static bool ServiceExists(string servicename)
{
    ServiceController[] services = ServiceController.GetServices();
    foreach (ServiceController s in services)
    {
        if (s.ServiceName == servicename)
        {
            return true;
        }
    }
    return false;
}

In this answer, Henk said that the non-use of Dispose() (or using) will not generate memory leaks, true or false?

Can I keep the previous code has it is or should I write someting like :

public static bool ServiceExists(string servicename)
{
    ServiceController[] services = ServiceController.GetServices();
    bool exists = false;

    foreach (ServiceController s in services)
    {
        using(s)
        {
            if (s.ServiceName == servicename)
            {
                exists = true;
            }
        }
    }

    return exists;
}

What are the risks to no using Dispose() (or using) in this case?

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

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

发布评论

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

评论(2

孤寂小茶 2024-12-21 09:05:47

如果未调用正确编写的对象的 Dispose 方法,则不会导致内存泄漏。如今,控制非托管资源的 .Net 对象应该通过 SafeHandle 实例。即使未调用 Dispose,这些也将确保释放本机内存。

但是,如果未调用 Dispose,则未正确编写的对象很可能会产生内存泄漏。我见过很多这样的物体的例子。

一般来说,如果您使用自己拥有的 IDisposable 实例,则应始终调用 Dispose。即使对象被正确编写,尽早而不是稍后清理非托管资源也是对您有利的。

编辑

正如 James 在评论中指出的那样,在一种情况下,不调用 Dispose 可能会导致内存泄漏。某些对象使用 Dispose 回调来从长期存在的事件中脱钩,如果它们保持附加状态,将导致对象驻留在内存中并构成泄漏。总是调用 Dispose 的另一个原因

A correctly written object shouldn't cause a memory leak if it's Dispose method isn't called. These days a .Net object which controls unmanaged resources should be doing so via a SafeHandle instance. These will ensure the native memory is freed even if Dispose is not called.

However it's very possible for objects which aren't written correctly to produce memory leaks if Dispose isn't called. I've seen many examples of such objects.

In general though if you are using an IDisposable instance which you own you should always call Dispose. Even if the object is correctly written it's to your benefit that unmanaged resources get cleaned up earlier instead of later.

EDIT

As James pointed out in the comments there is one case where not calling Dispose could cause a memory leak. Some objects use the Dispose callback to unhook from long lived events which if they stayed attached to would cause the object to reside in memory and constitute a leak. Yet another reason to always call Dispose

山川志 2024-12-21 09:05:47

这完全取决于 ServiceController.GetServices() 正在做什么。如果它在调用时创建 ServiceController 的新实例,则可能会导致内存泄漏,具体取决于它在 Dispose 方法中需要执行的操作(ServiceController)。

也就是说,在这种情况下添加“using”无论如何都不会修复它,就好像您确实需要在每个实例上调用 dispose (在这种情况下通过“using”隐式调用)一样,它不会因为只要找到 ServiceController 就会返回有一个匹配的名字。

因此,如果您的第一次迭代找到了匹配的 ServiceController,则所有其他 ServiceController 都不会被丢弃。

It all depends on what ServiceController.GetServices() is doing. If it is creating new instances of ServiceControllers when it is called, then it could cause a memory leak depending on what it needs to do (the ServiceController) in its Dispose method.

That said, adding 'using' in this case wouldn't fix it anyway as if you DID need to call dispose (implicitly via 'using' in this case) on each instance, it WOULDN'T as it returns whenever it finds a ServiceController with a matching name.

Therefore, if your first iteration found a matching ServiceController, all the other ServiceControllers wouldn't get disposed of anyway.

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