以下是翻译好的内容: 这段C#代码会引起内存泄漏问题吗?

huangapple go评论68阅读模式
英文:

Is the following code in c# cause memory leak issue?

问题

以下是代码的翻译部分:

我在想以下的代码是否会导致内存泄漏:

namespace ConsoleApplicationTest
{
    internal class Program
    {
        static void Main(string[] args)
        {
            CreateMemoryLeak();
            
            // 这里还有一些其他代码,使应用程序运行更长时间...
        }

        private static void CreateMemoryLeak()
        {
            new Foo();
        }
    }

    public class Foo
    {
        Bar bar = new Bar();

        public Foo()
        {
            bar.MyEventHandler += SomeMethod;
        }

        private void SomeMethod(object sender, EventArgs e)
        {
            // 在这里放一些漂亮但不相关的代码...
        }
    }

    public class Bar
    {
        public EventHandler MyEventHandler;
    }
}

根据我对事件处理程序(EventHandler)的理解,调用CreateMemoryLeak()会导致内存泄漏,因为只要Bar仍然"存活"或通过其事件处理程序对Foo有引用,Foo就不会被垃圾回收,而Bar也不会被垃圾回收,因为它存在于Foo的实例内。我的理解是否正确,或者是否会被垃圾回收,尽管Bar.MyEventHandler引用了它。如果不会内存泄漏,原因是什么?

谢谢。

英文:

I was wondering if the following code create a memory leak:

using System;

namespace ConsoleApplicationTest
{
    internal class Program
    {
        static void Main(string[] args)
        {
            CreateMemoryLeak();
            
            // Some other code here that make the application run longer...
        }

        private static void CreateMemoryLeak()
        {
            new Foo();
        }
    }

    public class Foo
    {
        Bar bar = new Bar();

        public Foo()
        {
            bar.MyEventHandler += SomeMethod;
        }

        private void SomeMethod(object sender, EventArgs e)
        {
            // Put some pretty yet irrelevant code here...
        }
    }

    public class Bar
    {
        public EventHandler MyEventHandler;
    }
}

From my understanding of how EventHandler work, calling CreateMemoryLeak() will create a memory leak, since Foo will not be garbage collected as long a Bar is "alive" or has a reference to Foo via his EventHandler and Bar will not be garbage collected, because it is living inside the instance of Foo. Is my understanding correct, or will be garbage collected, even though the Bar.MyEventHandler has a reference to it. And if it is not a memory, how so ?

Thank you

答案1

得分: 0

.net的垃圾收集器不会计算引用次数,它会检查对象是否从固定的根节点列表可达。因此,循环引用不是问题。在您的示例中,在CreateMemoryLeak结束后,FooBar的两个实例都变得不可达。因此,它们将在下一次垃圾回收运行时被回收,尽管它们相互引用。更多详细信息请参考:https://learn.microsoft.com/en-us/dotnet/standard/garbage-collection/fundamentals#memory-release

英文:

.net garbage collector does not count references, it checks reachability of the objects from the fixed list of root points. So, circular references is not a problem at all. For your sample both instances of Foo & Bar become unreachable after CreateMemoryLeak end. So, both will be collected on the next GC run, despite they referencing each other. More details https://learn.microsoft.com/en-us/dotnet/standard/garbage-collection/fundamentals#memory-release

huangapple
  • 本文由 发表于 2023年3月7日 08:46:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/75657115.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定