C#The';新';现有对象上的关键字

C#The';新';现有对象上的关键字,c#,object,garbage-collection,new-operator,C#,Object,Garbage Collection,New Operator,我想知道,一旦对象的引用被重新分配,对象(在C#中)会发生什么情况。例如: Car c = new Car("Red Car"); c = new Car("Blue Car"); 由于引用被重用,垃圾收集器是否会在“红色汽车”失去引用后处理它?或者是否需要实施单独的方法来处置“红色汽车” 我主要想知道的是,我要回收一个相对较大的对象,并且需要知道当它被重新创建时,是否有什么需要做的事情。在您的示例中,当c被分配给Blue Car时,c的Red Car实例将有资格进行垃圾收集。你不需要做任何事

我想知道,一旦对象的引用被重新分配,对象(在C#中)会发生什么情况。例如:

Car c = new Car("Red Car");
c = new Car("Blue Car");
由于引用被重用,垃圾收集器是否会在“红色汽车”失去引用后处理它?或者是否需要实施单独的方法来处置“红色汽车”


我主要想知道的是,我要回收一个相对较大的对象,并且需要知道当它被重新创建时,是否有什么需要做的事情。

在您的示例中,当
c
被分配给
Blue Car
时,
c
Red Car
实例将有资格进行垃圾收集。你不需要做任何事

查看这篇关于.NET垃圾收集器的MSDN文章(很旧,但仍然相关)

第一段说明了一切:

Microsoft.NET公共语言运行时环境中的垃圾收集完全免除了开发人员跟踪内存使用情况和知道何时释放内存的责任


创建一个新对象,并将其引用指定给变量
c
。同时,前一个对象(“红色汽车”)现在不再被引用,可能会被垃圾收集。

如果没有其他对红色汽车的引用,GC将在其下一个循环中收集它。你不需要任何额外的东西(除非它是一个有需要处理的流等的类)

垃圾收集器将处理汽车对象

垃圾收集器将拾取你的
红色汽车
对象并处理它


如果原始对象不再使用时需要释放资源,则可以调用自定义析构函数或实现IDisposable。

如果
Car
持有一些本机资源,则需要实现
IDisposable
,并在重新使用变量之前正确处理它。

垃圾收集器将当红色汽车不再扎根(无法到达)时,处理其清理。作为开发人员,您通常不必担心清理.Net中的内存

有三个注意事项需要提及:

  • 这不会马上发生。垃圾收集将在发生时发生。你无法预测
  • 如果该类型实现IDisposable,则由您确定是否调用了.Dispose()方法。使用
    语句是实现这一点的好方法
  • 你提到它是一个大物体。如果超过85000字节,它将存储在一个叫做大对象堆的地方,这个地方有非常不同的垃圾收集规则。允许经常回收此类物品可能会导致问题
  • 由于引用被重用,垃圾收集器是否会在“红色汽车”丢失其引用后处理它

    您可能以错误的方式看待此问题:

    c [*] ----> [Car { Name = "Red Car" }]  // Car c = new Car("Red Car")
    
    然后你的下一步:

    c [*]       [Car { Name = "Red Car"  }] // No chain of references to this object
       \------> [Car { Name = "Blue Car" }] // c = new Car("Blue Car")
    
    GC将出现并“收集”这些对象中的任何一个,这些对象在将来的某个时间点上都有。对于大多数任务,只要使用托管数据,就不必担心大型对象与小型对象之间的矛盾


    对于大多数任务,您在处理时只担心确定性内存管理。只要您遵循使用
    -block的最佳实践,

    我认为您应该实现IDispose接口来清理非托管资源

    public class car : IDispose 
    

    可能值得调用
    Dispose
    ,具体取决于所讨论的类型。假设没有对原始对象(包括未注册的事件处理程序)的其他引用,则您是正确的。@Phil:True但没有帮助。如果存在Dispose,则应调用它,但这是一个例外,仅当需要清理内存以外的资源时才需要。该类通过Assemble.Load()加载插件,并将类/插件存储到数组中。我想那会被认为是物体的一部分。我不确定这是否会改变anything@Richard:我不想说它得到“disposed”,因为这意味着如果定义了
    IDisposable.Dispose
    方法,就会调用它,但事实并非如此。所以这是误导。另外,我认为你对第一段的引用也有点误导
    IDiposable
    也是GC过程的一个重要部分,因此,虽然该段对于纯托管类型是正确的,但对于那些偶然发现您的答案的人来说,“完全免除”是非常误导的。请注意,对象是否具有引用不是GC正在检查的内容。GC正在检查对象是否存在来自已知活动对象的引用路径。一个对象可能有来自某个对象的引用,但如果该对象本身已经死了,那么该引用就不算了。谢谢,我很难确定要包含多少内容(我返回并添加了一点关于
    IDisposable
    )。我将更新以澄清。