Home All Groups Group Topic Archive Search About

Destroying objects, the IDisposable interface and memory management

Author
15 Jun 2009 9:31 PM
Andrew Falanga
Hi,

How can I force an objects destructor to execute?  I'm writing a WCF
server and client.  The server makes a dictionary of objects that are
operated on at the request of the client.  I wrote it to be a
dictionary because I saw that the dictionary had a remove method to
remove objects from the dictionary.  Now I thought that removing the
object would make it so that there was no more valid reference to the
object and thus garbage collection would come along and dispose of
it.  This isn't happening though.  I remove all elements in my
dictionary and the objects desctructors are not called.  The one way I
know this is that each object makes a temporary file for processing
data and should delete this temp file when the destructor is called.
However, these temp files hang out until the WCF server reaches the
obj.Close() method call.

So, how does one force a call to a destructor?

Andy

Author
15 Jun 2009 10:10 PM
gareth erskine-jones
On Mon, 15 Jun 2009 14:31:53 -0700 (PDT), Andrew Falanga
<af300***@gmail.com> wrote:

Show quoteHide quote
>Hi,
>
>How can I force an objects destructor to execute?  I'm writing a WCF
>server and client.  The server makes a dictionary of objects that are
>operated on at the request of the client.  I wrote it to be a
>dictionary because I saw that the dictionary had a remove method to
>remove objects from the dictionary.  Now I thought that removing the
>object would make it so that there was no more valid reference to the
>object and thus garbage collection would come along and dispose of
>it.  This isn't happening though.  I remove all elements in my
>dictionary and the objects desctructors are not called.  The one way I
>know this is that each object makes a temporary file for processing
>data and should delete this temp file when the destructor is called.
>However, these temp files hang out until the WCF server reaches the
>obj.Close() method call.
>
>So, how does one force a call to a destructor?

You can force garbage collection, with:

GC.Collect()

but that's rarely needed (or a good idea).

Normally you'd implement the IDisposable interface, and release your
unmanged resources in the Dispose method. You'd then call
Dispose(true) on each of your objects after removing them from the
dictionary.

GSEJ
Are all your drivers up to date? click for free checkup

Author
15 Jun 2009 10:16 PM
Peter Duniho
On Mon, 15 Jun 2009 14:31:53 -0700, Andrew Falanga <af300***@gmail.com> 
wrote:

> How can I force an objects destructor to execute?

You can't.  At best, you can have the finalizer (the "more correct" term 
for that special method) call a method that you can call explicitly when 
you want the same work to be done explicitly.

Typically, you'd name that method Dispose(), implement IDisposable, and 
Bob's your uncle.

> I'm writing a WCF
> server and client.  The server makes a dictionary of objects that are
> operated on at the request of the client.  I wrote it to be a
> dictionary because I saw that the dictionary had a remove method to
> remove objects from the dictionary.

The List<T> class also has a Remove() method.  So does ArrayList.  And any 
number of other collection classes.

Dictionary<TKey, TValue> might be the right class to use, or it might 
not.  But the presence of a Remove() method isn't what determines that.

> Now I thought that removing the
> object would make it so that there was no more valid reference to the
> object and thus garbage collection would come along and dispose of
> it.  This isn't happening though. [...]

That's right.  Assuming the object truly is unreachable, finalization and 
collection of the object might happen right away.  It might happen later.  
It might not happen at all.  Your code should not depend on garbage 
collection behavior, including execution of the finalizer.  Instead, 
implement IDisposable in objects that have unmanaged resources in need of 
cleaning up, and make sure to call the Dispose() method when you are done 
with the object.

Note that part of your issue may be that the dictionary instance isn't the 
only place the objects are referenced.  Your statement implying that the 
finalizer eventually does get called after some "obj.Close()" method is 
called (though you don't bother to tell us what "obj" is) suggests that 
the objects you expected to get finalized and collected are still being 
referenced somewhere else, until that Close() method is called.

Without a concise-but-complete code example that reliably demonstrates the 
issue, it's impossible to provide specific advice.  In the meantime, 
hopefully the above helps explain the basics.

Pete
Author
16 Jun 2009 4:19 PM
Andrew Falanga
On Jun 15, 4:16 pm, "Peter Duniho" <NpOeStPe***@nnowslpianmk.com>
wrote:
> On Mon, 15 Jun 2009 14:31:53 -0700, Andrew Falanga <af300***@gmail.com>  
> wrote:
>
> > How can I force an objects destructor to execute?
>
> You can't.  At best, you can have the finalizer (the "more correct" term  
> for that special method) call a method that you can call explicitly when  
> you want the same work to be done explicitly.
>

I didn't think so, but wanted to know if there's a way to do it.

> The List<T> class also has a Remove() method.  So does ArrayList.  And any  
> number of other collection classes.
>
> Dictionary<TKey, TValue> might be the right class to use, or it might  
> not.  But the presence of a Remove() method isn't what determines that.
>

That wasn't the reason.  I started with a List<> object but discarded
it because removing items from the list reordered the list and broke
my indexing methods.  The Dictionary<> object made more sense.

Show quoteHide quote
> > Now I thought that removing the
> > object would make it so that there was no more valid reference to the
> > object and thus garbage collection would come along and dispose of
> > it.  This isn't happening though. [...]
>
> That's right.  Assuming the object truly is unreachable, finalization and  
> collection of the object might happen right away.  It might happen later.  
> It might not happen at all.  Your code should not depend on garbage  
> collection behavior, including execution of the finalizer.  Instead,  
> implement IDisposable in objects that have unmanaged resources in need of  
> cleaning up, and make sure to call the Dispose() method when you are done  
> with the object.
>
> Note that part of your issue may be that the dictionary instance isn't the  
> only place the objects are referenced.  Your statement implying that the  
> finalizer eventually does get called after some "obj.Close()" method is  
> called (though you don't bother to tell us what "obj" is) suggests that  
> the objects you expected to get finalized and collected are still being  
> referenced somewhere else, until that Close() method is called.

I thought that mentioning I was making a WCF service it would be clear
that the obj.Close() call is the object of type WCFServer.  Sorry that
it wasn't as clear as I intended.



>
> Without a concise-but-complete code example that reliably demonstrates the  
> issue, it's impossible to provide specific advice.  In the meantime,  
> hopefully the above helps explain the basics.
>

Basically, what I have is this:

using System.Collections.Generic;
using some.class.library;  // this library does image comparisons
using both managed and unmanaged code

class WCFServer {
   int index = 0;
   Dictionary<int, ComparisonClass> graphics;

   int GetImgReference(string path) {
      graphics.Add(++index, ComparisonClass(path));

      return index;
   }

   bool RemoveImgReference(int index) {
      return graphics.Remove(index);
   }
}

class ServerProgram {
   void public static Main() {
      WCFServer myServ = new WCFServer();

      myServ.Open();

      Console.WriteLine("server started, press <enter> to exit");

      Console.ReadLine(); // wait

      WCFServer.Close();
   }
}


Bear in mind that I'm just developing things now.  Then, on the WCF
client side, the client makes a new class that calls to the server
using these functions.  So the server starts, opens the sockets and
waits for clients to connect.  The client calls the MakeImgReference
(path) function and obtains an index into the dictionary for the
objects stored there.  Then, using the RemoveImgReference(index)
function, deletes objects from the dictionary.  My plan was that by
removing the element from the dictionary whatever resources used by
that object would be freed and garbage collection would take place.
However, this isn't happening.

Thanks,
Andy

Bookmark and Share