Domanda

This has never really occurred to me, because I never gave it much thought when I migrated to C# from C++, but... is there a way to force freeing of memory right there and then for something like List, array, or even objects that don't implement IDisposable? Let me explain what's on my mind...

In C++, if I have want to create a dynamic array, I write something like this:

int* arr = NULL;
arr = new int[10];

...however, I have to delete it when I'm done, or there's going to be a memory leak:

delete [] arr;

Well, it doesn't seem like there's anything like that in C# or is there? I haven't been able to find. It appears that only objects that implement IDisposable interface can be forcefully disposed. So, is setting say... array to null and letting GC clean up the only way to clean up memory in that case?

I've read up on GC.Collect() and that forcing earlier collection is frowned upon, so I was wondering if there's anything singular for these types? I realize C# is not C++, I'm just curious to know if I'm missing something obvious.

È stato utile?

Soluzione

setting say... array to null and letting GC clean up the only way to clean up memory in that case

well, the first bit is probably wrong, unless arr was actually (say) a field of another object that is going to continue to live for a long period of time. In your example, arr was a local variable, and the GC and JIT conspire (when you're running release code, not debug) to know the lifetime of such variables very accurately. They know that arr isn't used again and is so eligible for garbage collection - there's no need to assign null to it.

Now, to the broader question - no, there's no way to hand memory back eagerly. It would actually be more work to allow you to tell the GC "please take back this block of memory now"1. GC.Collect, as you say, is frowned upon, because even that isn't really "please take back this block of memory I'm no longer using", it's "please run your full analysis to determine all blocks of memory that are no longer required, then perform compaction, etc".

1The managed memory system has a trivial way of keeping track of available memory for new allocations - it's at the end of the block of all previous allocations. So compaction is the only way that released memory can be reused.

Altri suggerimenti

No, there is no existing way to free memory used by single managed object in .Net.

You can either

  • manage native memory yourself (i.e. PInvoke for GlobalAloc functions)
  • force complete garbage collection after releasing all non-weak references to particular managed object( GC.Collect();GC.WaitForPendginFinalizers()

The classes of IDisposable interface implements method Dispose, which is the one for forcing object to be disposed.

But there is a Garbage Collector in C#, which automatically deletes all the object which are not referenced. It means that all local variables are deleted automatically when you leave its context, etc.

So in many cases, calling Dispose is not necessary ...

For general, if you want to free memory of object after its use, I recommend to use using statement:

using (... some object creation ...) 
{
    ... using object ...
}
// here, the object is disposed
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top