简体   繁体   中英

How do you get rid of an object in c#

In the following c# code, how do I get rid of the objects when it's no longer useful? Does it get taken care of automatically, or do I need to do something?

public void Test()
{
   object MyObject = new object();

   ... code ...
}

Automatically. When MyObject goes out of scope (at the end of Test), it's flagged for garbage collection. At some point in the future, the .NET runtime will clean up the memory for you

Edit: (I should point out for the sake of completeness that if you pass MyObject somewhere, it gets passed by reference, and will not be garbage collected - it's only when no more references to the object are floating around that the GC is free to collect it)

Edit: in a release build, MyObject will usually be collected as soon as it's unused (see my answer for more details --dp)

The short answer is: unless it has unmanaged resources (file handles etc) you don't need to worry.

The long answer is a bit more involved.

When .NET decides it wants to free up some memory, it runs the garbage collector . This looks for all the objects which are still in use, and marks them as such. Any local variable (in any stack frame of any thread) which may still be read counts as a root as do static variables. (In fact I believe that static variables are referenced via live Type objects, which are referenced via live AppDomain objects, but for the most part you can regard static variables as roots.)

The garbage collector looks at each object referred to by a root, and then finds more "live" references based on the instance variables within those objects. It recurses down, finding and marking more and more objects as "live". Once it's finished this process, it can then look at all the rest of the objects and free them.

That's a very broad conceptual picture - but it gets a lot more detailed when you think of the generational model of garbage collection, finalizers, concurrent collection etc. I strongly recommend that you read Jeff Richter's CLR via C# which goes into this in a lot of detail. He also has a two part article (back from 2000, but still very relevant) if you don't want to buy the book.

Of course all this doesn't mean you don't need to worry about memory usage and object lifetimes in .NET. In particular:

  • Creating objects pointlessly will cost performance. In particular, the garbage collector is fast but not free. Look for simple ways to reduce your memory usage as you code, but micro-optimising before you know you have a problem is also bad.
  • It's possible to "leak" memory by making objects reachable for longer than you intended. Two reasonably common causes of this are static variables and event subscriptions. (An event subscription makes the event handler reachable from the event publisher, but not the other way round.)
  • If you use more memory (in a live, reachable way) than you have available, your app will crash. There's not a lot .NET can do to prevent that!
  • Objects which use non-memory resources typically implement IDisposable . You should call Dispose on them to release those resources when you're finished with the object. Note that this doesn't free the object itself - only the garbage collector can do that. The using statement in C# is the most convenient way of calling Dispose reliably, even in the face of an exception.

其他答案是正确的,除非您的对象是实现IDisposable接口的类的实例,在这种情况下,您应该(显式或隐式地通过using语句)调用对象的Dispose方法。

In optimized code, it is possible and likely that MyObject will be collected before the end of the method. By default, the debug configuration in Visual Studio will build with the debug switch on and the optimize switch off which means that MyObject will be kept to the end of the method (so that you can look at the value while debugging). Building with optimize off (debug doesn't matter in this case) allows MyObject to be collected after it's determined to be unused. One way to force it to stay alive to the end of the method is to call GC.KeepAlive(MyObject) at the end of the method.

This will force the garbage collector to get rid of unused objects.

GC.Collect();
GC.WaitForPendingFinalizers();

If you want a specific object to be collected.

object A = new Object();
...
A = null;
GC.collect();
GC.WaitForPendingFinalizers();

它会自动处理。

Typically garbage collection can be depended on to cleanup, but if your object contains any unmanaged resources (database connections, open files etc) you will need to explicitly close those resources and/or exceute the dispose method on the object (if it implements IDisposable). This can lead to bugs so you need to be careful how you deal with these types of objects. Simply closing a file after using it is not always sufficient since an exception before the close executes will leave the file open. Either use a using block or a try-finally block.

Bottom line: "using" is your friend.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM