.NET构造函数和内存管理问题 来自C++等低级语言,并且看到了.NET内存管理是多么透明,我有一个音乐会,关于我写的一行代码。 在C++中,每一个对象(必须指定内存管理的设计实践和特性)需要有一个构造函数和一个析构函数。在.NET中,析构函数并不是经常需要的,而且对于何时需要析构函数以及如何使用析构函数有不同的模式。我的问题是。如果我有以下类似的代码(在VB.NET中,但同样适用于C#) Dim myObj作为新的MyClass()

.NET构造函数和内存管理问题 来自C++等低级语言,并且看到了.NET内存管理是多么透明,我有一个音乐会,关于我写的一行代码。 在C++中,每一个对象(必须指定内存管理的设计实践和特性)需要有一个构造函数和一个析构函数。在.NET中,析构函数并不是经常需要的,而且对于何时需要析构函数以及如何使用析构函数有不同的模式。我的问题是。如果我有以下类似的代码(在VB.NET中,但同样适用于C#) Dim myObj作为新的MyClass(),c#,.net,vb.net,memory-management,constructor,C#,.net,Vb.net,Memory Management,Constructor,后面是代码中的下一行 myObj = New MyClass( <some other parameters> ) myObj=新的MyClass() 上述情况是否会导致内存泄漏?对这种情况的正确思考方式是什么?否定。CLR使用引用计数器维护对所有实例的引用;每隔一段时间,内存垃圾收集器就会运行并找到所有没有代码引用的引用,然后释放内存 在您的情况下,这仅仅意味着在将来的某个时候,由于您不再引用MyClass的原始实例,垃圾收集器将为您释放它的内存。这是正常操作;所以你不用担心=

后面是代码中的下一行

myObj = New MyClass( <some other parameters> )
myObj=新的MyClass()

上述情况是否会导致内存泄漏?对这种情况的正确思考方式是什么?

否定。CLR使用引用计数器维护对所有实例的引用;每隔一段时间,内存垃圾收集器就会运行并找到所有没有代码引用的引用,然后释放内存


在您的情况下,这仅仅意味着在将来的某个时候,由于您不再引用MyClass的原始实例,垃圾收集器将为您释放它的内存。这是正常操作;所以你不用担心=D阴性。CLR使用引用计数器维护对所有实例的引用;每隔一段时间,内存垃圾收集器就会运行并找到所有没有代码引用的引用,然后释放内存


在您的情况下,这仅仅意味着在将来的某个时候,由于您不再引用MyClass的原始实例,垃圾收集器将为您释放它的内存。这是正常操作;所以你不用担心=D

它不会导致内存泄漏垃圾收集器将回收上一个对象


所有托管资源使用的内存将由垃圾收集器处理。

它不会导致内存泄漏垃圾收集器将回收上一个对象

所有托管资源使用的内存将由垃圾收集器处理。

否,这不会导致内存泄漏。你写的代码很好。关于C#(以及其他.NET语言),您必须记住的一点是它们是垃圾收集的

不同于C++,在这里你明确地负责创建和释放内存,而在托管的.NET世界中情况并非如此。您所要担心的就是创建对象。当不再有对它的任何剩余引用时,它就有资格进行垃圾收集。说真的,考虑到你在其他语言方面的背景,我知道这听起来很奇怪,但你真的应该让垃圾收集器担心这些事情。"正确的思考方式"的确是根本不去想!

事实上,您只需要在类使用非托管对象(如窗口句柄、GDI+对象等)或其他需要显式关闭的对象(文件句柄、数据库连接等)时编写析构函数(从而担心内存管理)。在.NET世界中,您希望尽可能少地编写析构函数,因为这样做会有轻微的性能损失。具体细节在于垃圾收集算法的实现,以及在什么时候可以收集对象,但您不应该尝试了解所有这些

需要记住的重要一点是,如果确实需要在对象被销毁时“清理”,则应该实现,就像许多在内部使用非托管对象的WinForms类(例如)一样

以下是一些很好的资源,可以帮助您进一步了解.NET的垃圾收集模型:

  • 关于MSDN
  • 里科·马里亚尼
  • 杰弗里·里希特
  • 安德鲁·亨特
不,这不会导致内存泄漏。你写的代码很好。关于C#(以及其他.NET语言),您必须记住的一点是它们是垃圾收集的

不同于C++,在这里你明确地负责创建和释放内存,而在托管的.NET世界中情况并非如此。您所要担心的就是创建对象。当不再有对它的任何剩余引用时,它就有资格进行垃圾收集。说真的,考虑到你在其他语言方面的背景,我知道这听起来很奇怪,但你真的应该让垃圾收集器担心这些事情。"正确的思考方式"的确是根本不去想!

事实上,您只需要在类使用非托管对象(如窗口句柄、GDI+对象等)或其他需要显式关闭的对象(文件句柄、数据库连接等)时编写析构函数(从而担心内存管理)。在.NET世界中,您希望尽可能少地编写析构函数,因为这样做会有轻微的性能损失。具体细节在于垃圾收集算法的实现,以及在什么时候可以收集对象,但您不应该尝试了解所有这些

需要记住的重要一点是,如果确实需要在对象被销毁时“清理”,则应该实现,就像许多在内部使用非托管对象的WinForms类(例如)一样

以下是一些很好的资源,可以帮助您进一步了解.NET的垃圾收集模型:

  • 关于MSDN
  • 里科·马里亚尼
  • 杰弗里·里希特
  • 安德鲁·亨特

    • 对.NET中的对象进行垃圾收集。您不需要删除它们

      一些保持非托管状态的对象(例如通过p/Invoke从C函数分配的对象),例如System.IO.S
      myObj = New MyClass( <some other parameters> )
      
      Stream s = ...
      ...
      s.Dispose();
      
      using(Stream s = ...)
      {
          ...
      } // Dispose is called automatically