英文:
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
结束后,Foo
和Bar
的两个实例都变得不可达。因此,它们将在下一次垃圾回收运行时被回收,尽管它们相互引用。更多详细信息请参考: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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论