Re: FileStream.Close() & GarbageCollection - Memory Leak Question



On Feb 4, 8:26 pm, Tom <Thomas-...@xxxxxxxxxxxxx> wrote:
Thank you Lasse Karlsen!!

I am less concerned about an error being in my code ... but still a
bit confused about understanding the inner workings of
GarbageCollection. I'm looking for a good list of the top 20 or so
most common causes of memory leaks in the C# environment.

The "Stream.Close Method" documentation states: "Closes the current
stream and releases any resources (such as sockets and file handles)
associated with the current stream."

I considered the memory a "resource" that would be freed but I have no
supporting evidence for this thought. :( The bridging between managed
and unmanaged components is certainly confusing. In my mind I thought
that if part of the component was unmanaged ... then all of it was?
Now, with your explanation, I am trying to accept that system level
buffers are also "managed" when they are created within the .Net
environment?

The only resource that's truly "managed" is memory in the garbage
collected .NET heap.

However, managed objects can still "own" unmanaged resources (pointers
to memory on the global heap, file and socket handles, etc.), which
should be released by calling a method like Close or Dispose.

If the object is designed correctly, then those unmanaged resources
will be released eventually even if you forget to call the method,
because the object will have a finalizer that runs when the GC
collects it. But you should avoid relying on that, because you never
know when the finalizer is going to run - the garbage collector works
at its own pace. That's a problem for files: users will be frustrated
when they can't move or delete a file that *should* be closed, but is
actually still open because the garbage collector hasn't gotten to it
yet.

I am use to unmanaged malloc(), free(), fclose() and _fcloseall(). I
guess I should think of the .Net File.OpenRead() as a method that
creates a "partially" managed object?

If you like. You don't need to remember which methods do that - just
look at the return type. Whenever an object implements the IDisposable
interface, that means you should call Dispose (or a similar method
like Close) when you're done using it. The "using" block in C# makes
that convenient in many cases.

What actually happens is the FileStream calls a Windows API function
to open the file, which returns a file handle, and that handle is
stored in a field of the object. But the handle is just a number, as
far as .NET is concerned, so the garbage collector doesn't
automatically know that it needs to be cleaned up.

You could think of the handle like a dry cleaning ticket. Your maid
(the garbage collector) looks at the pile of papers on your desk
(memory blocks on the managed heap) and throws them all away, not
realizing that one of them is the key to getting your suit back
(identifying an unmanaged resource). To her, it's just another paper.
So if you want to get your suit back, you have to bring the ticket
back to the cleaners (call Close or Dispose, which passes the handle
to a Windows API function) before the maid finds it.

In a technical sense, the dry cleaning ticket is indeed a piece of
paper like any other (FileStream is a managed object). The link
between that ticket and your suit is a semantic link in your mind, not
a physical aspect of the ticket itself.

I wish I could find a comprehensive list of unmanaged resources used
within the .Net environment. My incomplete list only has the two items
mentioned above: 1) Sockets, 2) File handles.

There are also handles for Windows objects like bitmaps, fonts, and
icons, and pointers to memory blocks allocated from the global and COM
heaps.

I've read: (i) In a mixed managed/unmanaged solution you must manually
free unmanaged memory allocations. (ii) Usage of Stream.Close() is
required to "avoid memory leaks". -- But these two statements don't
necessarily suggest the buffer portion in a FileStream object is
either managed or unmanaged.

You don't really need to worry about the internals of the
FileStream... just notice that it implements IDisposable.

Jesse
.



Relevant Pages

  • Re: Tracking down a garbage collection problem
    ... but I don't know what methods are available to the Ruby ... megabytes of memory; if I process many files in a single run then ... I would expect garbage collection to kick in along the way but it ... practice of software engineering, and what separates software ...
    (comp.lang.ruby)
  • Re: 386sx/25mhz compatibility
    ... I'd need to add hard drives also, ... a better computer out of the garbage. ... Pentium, mid-2001, suddenly better computers started appearing. ... later, I got a 50MHz 486 with 16megs of memory, for ten dollars. ...
    (comp.os.linux.hardware)
  • Re: Larry Wall, on Tcl
    ... Sure, if each chunk of memory allocated was only freed in one place, it wouldn't be too painful. ... It keeps the bug from being noticed unless the subsystem using slow physical memory to back the virtual memory is overwhelmed. ... Both of those are prevented by garbage collection. ... What do you do to explicitly free up registers in your C code when you're done with them? ...
    (comp.lang.tcl)
  • Re: Memory management/leak?
    ... I even took a look at the decompiled code for Random and DateTime (using ... I suspect this might be a bit faster and create ... less garbage than you calling DateTime.Now.Millisecond as DateTime.Now ... Of course the other thing you can do is run your code in a memory profiler. ...
    (microsoft.public.dotnet.languages.csharp)