473,320 Members | 1,951 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

garbage collection

Hello,

I have a c# application that creates a timer to fire every minute using
multithreading. On every minute it calls a Ping class that I made using
sockets.
It creates a new ping class then sets it to null when it’s done.

I noticed every time this class gets created I see the memory keeps getting
larger.
I think I should add Idisposable to my ping class and dispose of the memory
after the class is set to null.

Can someone give me their thoughts on this and maybe an example on how to
use the Idisposable class?
Thanks

Nov 17 '05 #1
36 1858
Hi Andre,

You might want to take a look at the following SDK topic:

http://msdn.microsoft.com/library/de...classtopic.asp

IDisposable is not a class; it's an Interface. And if your class employs any
Disposable classes, or interacts with any unmanged or marshalled resources,
setting it to null doesn't do much of anything. Read the article for
details.

--
HTH,

Kevin Spencer
Microsoft MVP
..Net Developer
Ambiguity has a certain quality to it.

"André" <An**@discussions.microsoft.com> wrote in message
news:DD**********************************@microsof t.com...
Hello,

I have a c# application that creates a timer to fire every minute using
multithreading. On every minute it calls a Ping class that I made using
sockets.
It creates a new ping class then sets it to null when it's done.

I noticed every time this class gets created I see the memory keeps
getting
larger.
I think I should add Idisposable to my ping class and dispose of the
memory
after the class is set to null.

Can someone give me their thoughts on this and maybe an example on how to
use the Idisposable class?
Thanks

Nov 17 '05 #2
Thanks Kevin,

I only use managed code. I am using the sockets class in C#

Does this mean I should not use the Idiposable interaface?

"Kevin Spencer" wrote:
Hi Andre,

You might want to take a look at the following SDK topic:

http://msdn.microsoft.com/library/de...classtopic.asp

IDisposable is not a class; it's an Interface. And if your class employs any
Disposable classes, or interacts with any unmanged or marshalled resources,
setting it to null doesn't do much of anything. Read the article for
details.

--
HTH,

Kevin Spencer
Microsoft MVP
..Net Developer
Ambiguity has a certain quality to it.

"André" <An**@discussions.microsoft.com> wrote in message
news:DD**********************************@microsof t.com...
Hello,

I have a c# application that creates a timer to fire every minute using
multithreading. On every minute it calls a Ping class that I made using
sockets.
It creates a new ping class then sets it to null when it's done.

I noticed every time this class gets created I see the memory keeps
getting
larger.
I think I should add Idisposable to my ping class and dispose of the
memory
after the class is set to null.

Can someone give me their thoughts on this and maybe an example on how to
use the Idisposable class?
Thanks


Nov 17 '05 #3
The System.Net.Sockets.Socket class implements IDisposable. This indicates
that a Socket should be disposed when you're through with it. Since your
class implements at least one Socket, it should ensure that the Socket(s) is
disposed when your class is finished with it.

This means that your class should employ structured exception handling and
other techniques to ensure that this happens. If the Socket is a publicly
exposed member of your class, implementing IDisposable could be a very good
idea, to ensure that any developer implementing your class does not forget
to Dispose the Socket. Your Dispose method would Dispose the Socket.

Classes that implement IDisposable are eventually Garbage-collected even if
they are not Disposed, but there is a significant delay in the release of
the unmanaged resources they use, which can cause the type of memory
build-up you observed.

--
HTH,

Kevin Spencer
Microsoft MVP
..Net Developer
Ambiguity has a certain quality to it.

"André" <An**@discussions.microsoft.com> wrote in message
news:E4**********************************@microsof t.com...
Thanks Kevin,

I only use managed code. I am using the sockets class in C#

Does this mean I should not use the Idiposable interaface?

"Kevin Spencer" wrote:
Hi Andre,

You might want to take a look at the following SDK topic:

http://msdn.microsoft.com/library/de...classtopic.asp

IDisposable is not a class; it's an Interface. And if your class employs
any
Disposable classes, or interacts with any unmanged or marshalled
resources,
setting it to null doesn't do much of anything. Read the article for
details.

--
HTH,

Kevin Spencer
Microsoft MVP
..Net Developer
Ambiguity has a certain quality to it.

"André" <An**@discussions.microsoft.com> wrote in message
news:DD**********************************@microsof t.com...
> Hello,
>
> I have a c# application that creates a timer to fire every minute using
> multithreading. On every minute it calls a Ping class that I made
> using
> sockets.
> It creates a new ping class then sets it to null when it's done.
>
> I noticed every time this class gets created I see the memory keeps
> getting
> larger.
> I think I should add Idisposable to my ping class and dispose of the
> memory
> after the class is set to null.
>
> Can someone give me their thoughts on this and maybe an example on how
> to
> use the Idisposable class?
> Thanks
>


Nov 17 '05 #4
Thanks Kevin,

Can you help me add the dispose interface?

This is my simple ping class. I looked at the example on Microsoft’s web
page, but not sure how to clean up the resources.

I have one class calling the ping (keepalive) class that calls it like this
every minute.

private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{

KeepAlive keep = new KeepAlive(Convert.ToInt32(LocalPort));
keep.ping();
keep = null;
}
//*******************************************

//Calls this class.

using System;
using System.Text;
using System.IO;
using System.Net;
using System.Net.Sockets;

namespace SSH2
{
public class KeepAlive
{
int _port;
internal KeepAlive(int port)
{
_port = port;
}

internal void ping()
{
try
{
Encoding ASCII = Encoding.ASCII;
IPEndPoint hostEndPoint;
IPAddress hostAddress = System.Net.IPAddress.Loopback;
int conPort = port;
string Get = "GET / HTTP/1.1\r\nHost: 127.0.0.1\r\nConnection:
Close\r\n\r\n";

Byte[] ByteGet = ASCII.GetBytes(Get);
byte[] RecvBytes = new byte[256];
hostEndPoint = new IPEndPoint(hostAddress, conPort);
Socket s= new Socket(AddressFamily.InterNetwork, SocketType.Stream,
ProtocolType.Tcp);
s.Connect(hostEndPoint);
s.Send(ByteGet, ByteGet.Length, 0);

s.Close();
}
catch
{
}

}

internal int port
{
get
{
return _port;
}
set
{
_port = value;
}
}
}
}

Nov 17 '05 #5
André,

In this particular case KeepAlive does not need to implement
IDisposable. This is because Socket is only used in the ping method.
With structured exception handling you can be sure that the Socket
always gets disposed inside that method. To make things easier use the
Socket inside a using block. This guarentees that Dispose will be
called on the Socket even if an exception occurs.

using (Socket s = new Socket(...))
{
s.Connect(...);
s.Send(...);
}
Brian

André wrote:
Thanks Kevin,

Can you help me add the dispose interface?

This is my simple ping class. I looked at the example on Microsoft's web
page, but not sure how to clean up the resources.

I have one class calling the ping (keepalive) class that calls it like this
every minute.

private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{

KeepAlive keep = new KeepAlive(Convert.ToInt32(LocalPort));
keep.ping();
keep = null;
}
//*******************************************

//Calls this class.

using System;
using System.Text;
using System.IO;
using System.Net;
using System.Net.Sockets;

namespace SSH2
{
public class KeepAlive
{
int _port;
internal KeepAlive(int port)
{
_port = port;
}

internal void ping()
{
try
{
Encoding ASCII = Encoding.ASCII;
IPEndPoint hostEndPoint;
IPAddress hostAddress = System.Net.IPAddress.Loopback;
int conPort = port;
string Get = "GET / HTTP/1.1\r\nHost: 127.0.0.1\r\nConnection:
Close\r\n\r\n";

Byte[] ByteGet = ASCII.GetBytes(Get);
byte[] RecvBytes = new byte[256];
hostEndPoint = new IPEndPoint(hostAddress, conPort);
Socket s= new Socket(AddressFamily.InterNetwork, SocketType.Stream,
ProtocolType.Tcp);
s.Connect(hostEndPoint);
s.Send(ByteGet, ByteGet.Length, 0);

s.Close();
}
catch
{
}

}

internal int port
{
get
{
return _port;
}
set
{
_port = value;
}
}
}


}


Nov 17 '05 #6
On Tue, 18 Oct 2005 08:39:04 -0700, André
<An**@discussions.microsoft.com> wrote:
Thanks Kevin,

Can you help me add the dispose interface?


The code you posted wouldn't be helped by the IDisposable interface
since the socket isn't a persistant resource.

I do have a couple of remarks about your code, including an unmanaged
resource leak. I made some changes to your code to make it cleaner.
Comments are inline:

internal void ping()
{
// Declaration need to be before try block since
// variable is used in finally block
Socket s = null;

try
{
Encoding ASCII = Encoding.ASCII;
IPEndPoint hostEndPoint;
IPAddress hostAddress = System.Net.IPAddress.Loopback;
int conPort = port;
string Get = "GET / HTTP/1.1\r\nHost: 127.0.0.1\r\nConnection:
Close\r\n\r\n";
Byte[] ByteGet = ASCII.GetBytes(Get);
byte[] RecvBytes = new byte[256];
hostEndPoint = new IPEndPoint(hostAddress, conPort);
Socket s= new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
s.Connect(hostEndPoint);
s.Send(ByteGet, ByteGet.Length, 0);
}
catch(SocketException) // Catch specific exceptions. Swallowing
// all exceptions are bad.
{

}
finally
{
// Everything in finally is called even if an exception has been
// thrown.

// The previous version would leak an unmanaged socket
// resource if an exception was thrown before s.Close() was
// called.

// Call s.Close() or s.Dispose() to release the socket.
// I personally prefer Dispose since it is more generic to the
// framework.
if(s!=null)
s.Dispose();
}
}

--
Marcus Andrén
Nov 17 '05 #7
ok, i've made the change. Do i just leave this code as it stands?

private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{

KeepAlive keep = new KeepAlive(Convert.ToInt32(LocalPort));
keep.ping();
keep = null;
}
"Brian Gideon" wrote:
André,

In this particular case KeepAlive does not need to implement
IDisposable. This is because Socket is only used in the ping method.
With structured exception handling you can be sure that the Socket
always gets disposed inside that method. To make things easier use the
Socket inside a using block. This guarentees that Dispose will be
called on the Socket even if an exception occurs.

using (Socket s = new Socket(...))
{
s.Connect(...);
s.Send(...);
}
Brian

André wrote:
Thanks Kevin,

Can you help me add the dispose interface?

This is my simple ping class. I looked at the example on Microsoft's web
page, but not sure how to clean up the resources.

I have one class calling the ping (keepalive) class that calls it like this
every minute.

private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{

KeepAlive keep = new KeepAlive(Convert.ToInt32(LocalPort));
keep.ping();
keep = null;
}
//*******************************************

//Calls this class.

using System;
using System.Text;
using System.IO;
using System.Net;
using System.Net.Sockets;

namespace SSH2
{
public class KeepAlive
{
int _port;
internal KeepAlive(int port)
{
_port = port;
}

internal void ping()
{
try
{
Encoding ASCII = Encoding.ASCII;
IPEndPoint hostEndPoint;
IPAddress hostAddress = System.Net.IPAddress.Loopback;
int conPort = port;
string Get = "GET / HTTP/1.1\r\nHost: 127.0.0.1\r\nConnection:
Close\r\n\r\n";

Byte[] ByteGet = ASCII.GetBytes(Get);
byte[] RecvBytes = new byte[256];
hostEndPoint = new IPEndPoint(hostAddress, conPort);
Socket s= new Socket(AddressFamily.InterNetwork, SocketType.Stream,
ProtocolType.Tcp);
s.Connect(hostEndPoint);
s.Send(ByteGet, ByteGet.Length, 0);

s.Close();
}
catch
{
}

}

internal int port
{
get
{
return _port;
}
set
{
_port = value;
}
}
}
}


Nov 17 '05 #8
Yes, that's fine. Except, you really don't need to set the object
reference to null.

André wrote:
ok, i've made the change. Do i just leave this code as it stands?

private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{

KeepAlive keep = new KeepAlive(Convert.ToInt32(LocalPort));
keep.ping();
keep = null;
}


Nov 17 '05 #9
I still notice that the memory usage is getting higher each time the ping is
created. I know that the Garbage collection will get to it when it does.
Should I call the GC.collect? or just let it be?

Also, when is a time that I should use the IDisposable interface? I’m still
new to GC

Thanks
"Brian Gideon" wrote:
Yes, that's fine. Except, you really don't need to set the object
reference to null.

André wrote:
ok, i've made the change. Do i just leave this code as it stands?

private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{

KeepAlive keep = new KeepAlive(Convert.ToInt32(LocalPort));
keep.ping();
keep = null;
}


Nov 17 '05 #10
That's okay. Let it be.

If KeepAlive holds a class level reference to the Socket then KeepAlive
would be a candidate for implementing IDisposable. More specifically,
if the same Socket instance were used across different method calls on
KeepAlive then it would be imperative to implement IDisposable.

André wrote:
I still notice that the memory usage is getting higher each time the pingis
created. I know that the Garbage collection will get to it when it does.
Should I call the GC.collect? or just let it be?

Also, when is a time that I should use the IDisposable interface? I'm still
new to GC

Thanks
"Brian Gideon" wrote:
Yes, that's fine. Except, you really don't need to set the object
reference to null.

André wrote:
ok, i've made the change. Do i just leave this code as it stands?

private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{

KeepAlive keep = new KeepAlive(Convert.ToInt32(LocalPort));
keep.ping();
keep = null;
}



Nov 17 '05 #11
socket is managed, socket implements idisposable, so no matter when, when
socket will be garbage collected (sure it will be), its Dispose() method
will be called.why bother with idisposable? am i missing something?
Nov 17 '05 #12

"The Crow" <q> wrote in message
news:OE**************@TK2MSFTNGP15.phx.gbl...
socket is managed, socket implements idisposable, so no matter when, when
socket will be garbage collected (sure it will be), its Dispose() method
will be called.why bother with idisposable? am i missing something?


Dispose is not called when the sockect is GC'd. Dispose must be called
explicitely.

Willy.
Nov 17 '05 #13
then why there is something like Dispose(bool disposing) ????
Nov 17 '05 #14
Yes, it will be disposed. Eventually.

Why bother with calling Dispose? I think your original post answered THAT
question.

Look, you're already using a try/catch block. Add a finally block and
dispose that sucker. It's as easy as that. If you really want to know all
the technical details, download the FREE Microsoft .Net SDK:

http://www.microsoft.com/downloads/d...displaylang=en

--
HTH,

Kevin Spencer
Microsoft MVP
..Net Developer
Ambiguity has a certain quality to it.

"The Crow" <q> wrote in message
news:OE**************@TK2MSFTNGP15.phx.gbl...
socket is managed, socket implements idisposable, so no matter when, when
socket will be garbage collected (sure it will be), its Dispose() method
will be called.why bother with idisposable? am i missing something?

Nov 17 '05 #15
On Wed, 19 Oct 2005 09:17:27 +0300, "The Crow" <q> wrote:
socket is managed, socket implements idisposable, so no matter when, when
socket will be garbage collected (sure it will be), its Dispose() method
will be called.why bother with idisposable? am i missing something?


Dispose doesn't have anything to do with garbage collection. The
garbage collector basically has the following functionality:

1) Find objects that are eligible for garbage collection.
2) If the object has a finalizer, run it.
3) Mark the memory the object used as availible.

The problem with garbage collectors is that they aren't deterministic.
It could very well be 10 minutes or longer between the time that an
object is eligible for collection and the time that it is actually
collected.

This can be a problem when dealing with resources that can't wait
around for the garbage collector to run. The most common example being
operating system handles of different kinds. In those cases the
programmer manually has to tell the object to dispose of the resource,
which is the reason why the Disposable pattern exists.

Here is an example:

using System;
using System.IO;

class Test
{
string name = "test.txt";

// Safe write that disposes of the StreamWriter object
public static void WriteSafe()
{
//Note: the using construct will automatically call Dispose on
// the StreamWriter object when in leaves the scope.
using(StreamWriter sw = new StreamWriter(name))
{
sw.Write("Test");
}
}

// Write which doesn't dispose of the StreamWriter object
public static void WriteUnsafe()
{
StreamWriter sw = new StreamWriter(name);
sw.Write("Test");
}

public static void Main()
{
WriteSafe();
//The file test.txt has been closed by the Dispose() method
WriteUnsafe();
//The file test.txt is open
Gc.Collect();
//The file test.txt has been closed by the StreamWriter
//finalizer (which most likely called the Dispose() method)
WriteUnsafe();
//The file test.txt is open
WriteUnsafe(); //This method call throws an exception, because the
//file is already open.
}
}

--
Marcus Andrén
Nov 17 '05 #16
I believe this snippet:
<snip>
try
{
Encoding ASCII = Encoding.ASCII;
IPEndPoint hostEndPoint;
IPAddress hostAddress = System.Net.IPAddress.Loopback;
int conPort = port;
string Get = "GET / HTTP/1.1\r\nHost: 127.0.0.1\r\nConnection:
Close\r\n\r\n";

Byte[] ByteGet = ASCII.GetBytes(Get);
byte[] RecvBytes = new byte[256];
hostEndPoint = new IPEndPoint(hostAddress, conPort);
Socket s= new Socket(AddressFamily.InterNetwork, SocketType.Stream,
ProtocolType.Tcp);
s.Connect(hostEndPoint);
s.Send(ByteGet, ByteGet.Length, 0);

s.Close();
}
catch
{
}
</snip>

could be changed to:

<NewSnip>
Encoding ASCII = Encoding.ASCII;
IPEndPoint hostEndPoint;
IPAddress hostAddress = System.Net.IPAddress.Loopback;
int conPort = port;

Byte[] ByteGet = ASCII.GetBytes("GET / HTTP/1.1\r\nHost:
127.0.0.1\r\nConnection: Close\r\n\r\n");
byte[] RecvBytes = new byte[256];
hostEndPoint = new IPEndPoint(hostAddress, conPort);
using (Socket s= new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp))
{
s.Connect(hostEndPoint);
s.Send(ByteGet, ByteGet.Length, 0);
s.Shutdown();
// shouldn't need to call close explicitly; Dispose should handle this
// note that by using the using construct, Dispose is called.
}
</NewSnip>

The main reason you should implement IDispose in one of your own classes
is to ensure that unmanaged resources (Database connections is the
classic example) are released.
You might find this template helpful:
<ClassImplementingDispose>
class Billy: IDisposable
{
private bool mDisposed = false;

public void doStuff()
{
// do this in each public method in case user called dispose,
// but then tried to call another method
if ( mDisposed ) throw new ObjectDisposedException();
// do what you normally do.
}

/// <summary>
/// If SupressFinalize wasn't there, the gc would have to do all the
/// extra work that is required for objects in the finalization queue.
/// </summary>
public void Dispose()
{
Dispose( true );
GC.SuppressFinalize(this);
}

protected virtual void Dispose( bool disposing )
{
if ( disposing )
{
// dispose any dependant managed objects if necessary.
// You don't want this to happen when the GC is calling this code
// because you have no idea what state other objects would be in at
that point.
disposed = true;
}
// Free unmanaged resources here.
}

~Billy()
{
Dispose( false );
Debug.Assert(false, "You are using this object improperly. Create in
using construct or ensure to call Dispose()");
}
}
</ClassImplementingDispose>

André wrote:
Thanks Kevin,

Can you help me add the dispose interface?

This is my simple ping class......

Nov 17 '05 #17
Willy Denoyette [MVP] <wi*************@telenet.be> wrote:
"The Crow" <q> wrote in message
news:OE**************@TK2MSFTNGP15.phx.gbl...
socket is managed, socket implements idisposable, so no matter when, when
socket will be garbage collected (sure it will be), its Dispose() method
will be called.why bother with idisposable? am i missing something?


Dispose is not called when the sockect is GC'd. Dispose must be called
explicitely.


As far as I can see, it *is* called when it's finalized.

This short program demonstrates that:

using System;
using System.Net.Sockets;

public class Test : Socket
{
public Test(AddressFamily addressFamily,
SocketType socketType,
ProtocolType protocolType)
: base (addressFamily, socketType, protocolType)
{
}

protected override void Dispose (bool disposing)
{
base.Dispose(true);
Console.WriteLine ("Disposed!");
}

static void Main()
{
Test t = new Test(AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.IP);

t = null;
GC.Collect();
GC.WaitForPendingFinalizers();
Console.WriteLine ("Finishing");
}
}

Are you trying to stress the difference between something being GC'd
and something being finalized?

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Nov 17 '05 #18

"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
Willy Denoyette [MVP] <wi*************@telenet.be> wrote:
"The Crow" <q> wrote in message
news:OE**************@TK2MSFTNGP15.phx.gbl...
> socket is managed, socket implements idisposable, so no matter when,
> when
> socket will be garbage collected (sure it will be), its Dispose()
> method
> will be called.why bother with idisposable? am i missing something?


Dispose is not called when the sockect is GC'd. Dispose must be called
explicitely.


As far as I can see, it *is* called when it's finalized.

This short program demonstrates that:

using System;
using System.Net.Sockets;

public class Test : Socket
{
public Test(AddressFamily addressFamily,
SocketType socketType,
ProtocolType protocolType)
: base (addressFamily, socketType, protocolType)
{
}

protected override void Dispose (bool disposing)
{
base.Dispose(true);
Console.WriteLine ("Disposed!");
}

static void Main()
{
Test t = new Test(AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.IP);

t = null;
GC.Collect();
GC.WaitForPendingFinalizers();
Console.WriteLine ("Finishing");
}
}

Are you trying to stress the difference between something being GC'd
and something being finalized?


Yes, this is what I want to stress, while it's true that the Finalizer
thread kicks in on request of a GC run, there no strong guarantee that your
Finalize (that calls your Dispose(bool)) method will execute at the next
Finalizer run, there are (very rare) cases in which your Finalizer might
never be called at all. That said, when you expect deterministic disposal of
your unmanaged resources, you need an explicit call to Dispose (or use the
using statement for fine grained scopes), relying on the Finalizer offers
you non-deterministic disposals.
Willy.
Nov 17 '05 #19
I believe those rare cases where the finalizer doesn't run at all can
be mitigated with the new constrained execution regions technology in
version 2. It is an interesting addition to the framework.

Brian

Willy Denoyette [MVP] wrote:
Yes, this is what I want to stress, while it's true that the Finalizer
thread kicks in on request of a GC run, there no strong guarantee that your
Finalize (that calls your Dispose(bool)) method will execute at the next
Finalizer run, there are (very rare) cases in which your Finalizer might
never be called at all. That said, when you expect deterministic disposal of
your unmanaged resources, you need an explicit call to Dispose (or use the
using statement for fine grained scopes), relying on the Finalizer offers
you non-deterministic disposals.
Willy.


Nov 17 '05 #20
skeet, what u have seen is, Socket destructor calls Dispose(true); this is
not a necessarity. the sample code explains everything.
http://msdn.microsoft.com/library/de...sposeTopic.asp
Nov 17 '05 #21
yes it seems interesting, but in respect to our discussion, finalizer or
desctructor does not call Dispose (at least destructor doesnt have to.).

one more interesting thing. compile and run that code. and see that it
definetly works!!


Nov 17 '05 #22
sorry for the second paragraph. you can ignore it.
Nov 17 '05 #23
The destructor is the finalizer. And the object will be destroyed when
Finalize() is called by the GC. Not before. Setting a field or variable to
null has no effect on the object it references. It is a pointer. You just
point it somewhere else. The object is unaffected.

--
HTH,

Kevin Spencer
Microsoft MVP
..Net Developer
Ambiguity has a certain quality to it.

"The Crow" <q> wrote in message
news:Ob**************@TK2MSFTNGP14.phx.gbl...
skeet, what u have seen is, Socket destructor calls Dispose(true); this is
not a necessarity. the sample code explains everything.
http://msdn.microsoft.com/library/de...sposeTopic.asp

Nov 17 '05 #24
Brian,

Right, the cases that the Finalizer doesn't run at all are rare, but you
would be supprised how many times I've seen it happen in scenarios where COM
interop is used on threads that are failing to pump the windows message
queue, or in Finalize methods that make blocking calls in unmanaged code
:-(.
Indeed, Constrained execution regions (CER's) are a great addition to the
framework, and a great tool in hosted environments.
Willy.
"Brian Gideon" <br*********@yahoo.com> wrote in message
news:11*********************@o13g2000cwo.googlegro ups.com...
I believe those rare cases where the finalizer doesn't run at all can
be mitigated with the new constrained execution regions technology in
version 2. It is an interesting addition to the framework.

Brian

Willy Denoyette [MVP] wrote:
Yes, this is what I want to stress, while it's true that the Finalizer
thread kicks in on request of a GC run, there no strong guarantee that
your
Finalize (that calls your Dispose(bool)) method will execute at the next
Finalizer run, there are (very rare) cases in which your Finalizer might
never be called at all. That said, when you expect deterministic disposal
of
your unmanaged resources, you need an explicit call to Dispose (or use
the
using statement for fine grained scopes), relying on the Finalizer offers
you non-deterministic disposals.
Willy.

Nov 17 '05 #25
Kevin,
The Finalize method is called on ran on the "finalizer" thread (an high
priority thread) after the GC has done it's marks/sweep run, but this
decision is mabe by the EE not directly by the GC, and only when there are
finalizable objects in the "ready for finalization" queue, when no such
objects are queued, the finalizer thread is not started (why would it?).

Willy.

"Kevin Spencer" <ke***@DIESPAMMERSDIEtakempis.com> wrote in message
news:ey*************@TK2MSFTNGP10.phx.gbl...
The destructor is the finalizer. And the object will be destroyed when
Finalize() is called by the GC. Not before. Setting a field or variable to
null has no effect on the object it references. It is a pointer. You just
point it somewhere else. The object is unaffected.

--
HTH,

Kevin Spencer
Microsoft MVP
.Net Developer
Ambiguity has a certain quality to it.

"The Crow" <q> wrote in message
news:Ob**************@TK2MSFTNGP14.phx.gbl...
skeet, what u have seen is, Socket destructor calls Dispose(true); this
is not a necessarity. the sample code explains everything.
http://msdn.microsoft.com/library/de...sposeTopic.asp


Nov 17 '05 #26
Technically true, but you might as well say that an ignition key doesn't
cause exhaust fumes to exit the exhaust pipe of a car. It's a chain of
events that is all about Garbage Collection, and initialized by Garbage
Collection. In the context of this discussion, we're talking about objects
(Sockets) which WILL be finalized. The technical details are not
particularly relevant to this particular discussion. It all started with the
OP asking why his class was accumulating memory, and when told that he
needed to Dispose Sockets, he wanted to know why. Maybe I'm too concerned
with results. I do have my times of pure technological research, and it is
certainly worthwhile. However, those times don't occur when I'm trying to
debug something!

--
;-),

Kevin Spencer
Microsoft MVP
..Net Developer
Ambiguity has a certain quality to it.

"Willy Denoyette [MVP]" <wi*************@telenet.be> wrote in message
news:%2****************@TK2MSFTNGP15.phx.gbl...
Kevin,
The Finalize method is called on ran on the "finalizer" thread (an high
priority thread) after the GC has done it's marks/sweep run, but this
decision is mabe by the EE not directly by the GC, and only when there are
finalizable objects in the "ready for finalization" queue, when no such
objects are queued, the finalizer thread is not started (why would it?).

Willy.

"Kevin Spencer" <ke***@DIESPAMMERSDIEtakempis.com> wrote in message
news:ey*************@TK2MSFTNGP10.phx.gbl...
The destructor is the finalizer. And the object will be destroyed when
Finalize() is called by the GC. Not before. Setting a field or variable
to null has no effect on the object it references. It is a pointer. You
just point it somewhere else. The object is unaffected.

--
HTH,

Kevin Spencer
Microsoft MVP
.Net Developer
Ambiguity has a certain quality to it.

"The Crow" <q> wrote in message
news:Ob**************@TK2MSFTNGP14.phx.gbl...
skeet, what u have seen is, Socket destructor calls Dispose(true); this
is not a necessarity. the sample code explains everything.
http://msdn.microsoft.com/library/de...sposeTopic.asp



Nov 17 '05 #27
i think you didnt read the code example. here it is :

using System;
using System.ComponentModel;

public class DisposeExample
{
public class MyResource: IDisposable
{
private IntPtr handle;
private Component component = new Component();
private bool disposed = false;
public MyResource(IntPtr handle)
{
this.handle = handle;
}

public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}

private void Dispose(bool disposing)
{
if(!this.disposed)
{
if(disposing)
{
component.Dispose();
}

CloseHandle(handle);
handle = IntPtr.Zero;
}
disposed = true;
}

[System.Runtime.InteropServices.DllImport("Kernel32 ")]
private extern static Boolean CloseHandle(IntPtr handle);

~MyResource()
{
Dispose(false); // This line is very important.... someone can
not include it.
}
}
public static void Main()
{
// Insert code here to create
// and use the MyResource object.
}
}
Nov 17 '05 #28
Hmm...I suppose it's me you are replying to, right?
When a class implement IDisposable it better adheres to the disposable
pattern, that is, a type that implements IDisposable should also have a
finalizer (called a destructor in C#), and that finalizer should call
Dispose(false).

But this is not my point, my point is that you should call dispose() when
you are done with the object if you want deterministic release of the
underlying resources, relying on finalize (your destructor ~) to call
Dispose(false) gives you non deterministic release, and should be avoided,
it's just a safety net to handle the cases that someone forgets to call
Dispose().

That's why I implement it as:

~MyResource()
{
Debug.Writeline("BUG... you should call dispose instead of
relying on the finalizer");
Dispose(false);
}

I'm also not clear on what you mean by this:
// This line is very important.... someone can not include it. Guess you meant something like this:// This line is very important.... someone can not omit it.
Willy.

PS. Note the difference between Dispose() and Dispose(bool), in my replies?
the first must be called explicitely, the second is called by the finalize
methods (when the finalizer runs).
"The Crow" <q> wrote in message
news:%2****************@TK2MSFTNGP09.phx.gbl...i think you didnt read the code example. here it is :

using System;
using System.ComponentModel;

public class DisposeExample
{
public class MyResource: IDisposable
{
private IntPtr handle;
private Component component = new Component();
private bool disposed = false;
public MyResource(IntPtr handle)
{
this.handle = handle;
}

public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}

private void Dispose(bool disposing)
{
if(!this.disposed)
{
if(disposing)
{
component.Dispose();
}

CloseHandle(handle);
handle = IntPtr.Zero;
}
disposed = true;
}

[System.Runtime.InteropServices.DllImport("Kernel32 ")]
private extern static Boolean CloseHandle(IntPtr handle);

~MyResource()
{
Dispose(false); // This line is very important.... someone can
not include it.
}
}
public static void Main()
{
// Insert code here to create
// and use the MyResource object.
}
}

Nov 17 '05 #29
yes. the whole point is "call dispose() when as soon as you done your job"
Nov 17 '05 #30

"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
Willy Denoyette [MVP] <wi*************@telenet.be> wrote:
"The Crow" <q> wrote in message
news:OE**************@TK2MSFTNGP15.phx.gbl...
> socket is managed, socket implements idisposable, so no matter when,
> when
> socket will be garbage collected (sure it will be), its Dispose()
> method
> will be called.why bother with idisposable? am i missing something?


Dispose is not called when the sockect is GC'd. Dispose must be called
explicitely.


As far as I can see, it *is* called when it's finalized.

This short program demonstrates that:

using System;
using System.Net.Sockets;

public class Test : Socket
{
public Test(AddressFamily addressFamily,
SocketType socketType,
ProtocolType protocolType)
: base (addressFamily, socketType, protocolType)
{
}

protected override void Dispose (bool disposing)
{
base.Dispose(true);
Console.WriteLine ("Disposed!");
}

static void Main()
{
Test t = new Test(AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.IP);

t = null;
GC.Collect();
GC.WaitForPendingFinalizers();
Console.WriteLine ("Finishing");
}
}

Are you trying to stress the difference between something being GC'd
and something being finalized?

--

To further illustrate my point, following is a sample (based on yours) that
illustrates how easy it is to block the finalizer thread.
This sample includes a class DogWrapper that wraps a simple COM object Dog,
in Main I create an instance of Dog and calls a method on it.

The output (except ***) looks like:

Woef!!
Test Disposed!
Finalizing DogWrapper !
*** 5 seconds delay here (10 * 0.5 secs.)
Finishing
Dog object Disposed!
Test Disposed!
Test Disposed!
Test Disposed!
Test Disposed!
Test Disposed!
Test Disposed!
Test Disposed!
Test Disposed!
Test Disposed!

Notice the time when "Finishing" is output... at program exit time, but
before the finalizer runs! That means that from the moment on that the
"Finalizer thread" enters DogWrapper's Finalize (ReleaseComObject to be
precise) it will block until it gets aborted and restarted by the CLR at
process shutdown time.
Note that this doesn't stop the GC nor the program to run (but how long?),
however, you will leak the resources you intended to release through the
destructor calling Dispose(false) and your "finalizable instances" will
finally exhaust the GC heap.
Note that the same can happen if the finalizer thread gets stuck (or blocks
for a long time) in unmanaged code.

using System;
using System.Net.Sockets;
using System.Reflection;
using System.Runtime.InteropServices;
using Project; // IA for Dog

public class DogWrapper : IDisposable
{
Dog madDog;
public void Bark()
{
madDog= new Dog();
madDog.Bark();
}
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if(!this.disposed)
{
Marshal.ReleaseComObject(madDog);
GC.Collect();
GC.WaitForPendingFinalizers();
madDog= null;
Console.WriteLine ("Dog object Disposed!");
}
this.disposed = true;
}
~T()
{
Console.WriteLine ("Finalizing DogWrapper !");
Dispose(false);
}
}
public class Test : Socket
{
public Test(AddressFamily addressFamily,
SocketType socketType,
ProtocolType protocolType)
: base (addressFamily, socketType, protocolType)
{
}

protected override void Dispose (bool disposing)
{
base.Dispose(true);
Console.WriteLine ("Test Disposed!");
}
[STAThread]
static void Main()
{
T te = new T();
GC.Collect();
Console.WriteLine(te.GetVersion());
for (int i = 0; i < 10; i++)
{
Test t = new Test(AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.IP);
GC.Collect();
System.Threading.Thread.Sleep(500);
}
Console.WriteLine ("Finishing");
}
}

Nov 17 '05 #31
Willy Denoyette [MVP] <wi*************@telenet.be> wrote:
Hmm...I suppose it's me you are replying to, right?
When a class implement IDisposable it better adheres to the disposable
pattern, that is, a type that implements IDisposable should also have a
finalizer (called a destructor in C#), and that finalizer should call
Dispose(false).


Not all classes that implement IDisposable need a finalizer - indeed, I
would argue that *most* don't.

StreamReader is a good example of this - it implements IDisposable to
close the stream it wraps, but it doesn't need a finalizer because it
doesn't *directly* hold any unmanaged resources. Instead, it relies on
teh stream that it wraps having a finalizer.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Nov 17 '05 #32
then in our example, the socket wrapper class doesnt have to call dispose of
socket. because socket.Dispose() will be called by the runtime. (probably in
the same garbage collection run.) but what if the socket object in the
wrapper object referenced by another object outside of the wrapper object?
Nov 17 '05 #33

"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
Willy Denoyette [MVP] <wi*************@telenet.be> wrote:
Hmm...I suppose it's me you are replying to, right?
When a class implement IDisposable it better adheres to the disposable
pattern, that is, a type that implements IDisposable should also have a
finalizer (called a destructor in C#), and that finalizer should call
Dispose(false).


Not all classes that implement IDisposable need a finalizer - indeed, I
would argue that *most* don't.

StreamReader is a good example of this - it implements IDisposable to
close the stream it wraps, but it doesn't need a finalizer because it
doesn't *directly* hold any unmanaged resources. Instead, it relies on
teh stream that it wraps having a finalizer.


Agreed, but I was talking about base types, and - sorry about the
confusion - what I said is not what I meant.
What I meant to say was, that every type that has a finalizer should
implement IDisposable. This gives users of the type a means to perform
deterministic clean-up of the same resources which the finalizer is
responsible for.
Sure, you may also implement Dispose on types without finalizers, e.g when
transitively disposing of object state or when using types which manage
their resources with finalizers allready.
Note that value types are an exception because they can't have a finalizer,
but I think this is a very simple rule; If you have (say need) a finalizer,
you want Dispose().

Willy.
Nov 17 '05 #34

"Willy Denoyette [MVP]" <wi*************@telenet.be> wrote in message
news:ud**************@TK2MSFTNGP10.phx.gbl...

"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
Willy Denoyette [MVP] <wi*************@telenet.be> wrote:
Hmm...I suppose it's me you are replying to, right?
When a class implement IDisposable it better adheres to the disposable
pattern, that is, a type that implements IDisposable should also have a
finalizer (called a destructor in C#), and that finalizer should call
Dispose(false).


Not all classes that implement IDisposable need a finalizer - indeed, I
would argue that *most* don't.

StreamReader is a good example of this - it implements IDisposable to
close the stream it wraps, but it doesn't need a finalizer because it
doesn't *directly* hold any unmanaged resources. Instead, it relies on
teh stream that it wraps having a finalizer.


I forgot to say in my previous reply that StreamReader does not "implement"
IDisposable it just implements Dispose(bool) that calls it's base
(TextReader.Dispose(bool)) which implements IDisposable though.

Willy.


Nov 17 '05 #35
<"The Crow" <q>> wrote:
then in our example, the socket wrapper class doesnt have to call dispose of
socket. because socket.Dispose() will be called by the runtime. (probably in
the same garbage collection run.) but what if the socket object in the
wrapper object referenced by another object outside of the wrapper object?


A wrapper class shouldn't have a finalizer, but it *should* implement
IDisposable to allow the user to dispose of the "wrapped" resource
early.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Nov 17 '05 #36
Thanks everyone

"Brad Wood" wrote:
I believe this snippet:
<snip>
try
{
Encoding ASCII = Encoding.ASCII;
IPEndPoint hostEndPoint;
IPAddress hostAddress = System.Net.IPAddress.Loopback;
int conPort = port;
string Get = "GET / HTTP/1.1\r\nHost: 127.0.0.1\r\nConnection:
Close\r\n\r\n";

Byte[] ByteGet = ASCII.GetBytes(Get);
byte[] RecvBytes = new byte[256];
hostEndPoint = new IPEndPoint(hostAddress, conPort);
Socket s= new Socket(AddressFamily.InterNetwork, SocketType.Stream,
ProtocolType.Tcp);
s.Connect(hostEndPoint);
s.Send(ByteGet, ByteGet.Length, 0);

s.Close();
}
catch
{
}
</snip>

could be changed to:

<NewSnip>
Encoding ASCII = Encoding.ASCII;
IPEndPoint hostEndPoint;
IPAddress hostAddress = System.Net.IPAddress.Loopback;
int conPort = port;

Byte[] ByteGet = ASCII.GetBytes("GET / HTTP/1.1\r\nHost:
127.0.0.1\r\nConnection: Close\r\n\r\n");
byte[] RecvBytes = new byte[256];
hostEndPoint = new IPEndPoint(hostAddress, conPort);
using (Socket s= new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp))
{
s.Connect(hostEndPoint);
s.Send(ByteGet, ByteGet.Length, 0);
s.Shutdown();
// shouldn't need to call close explicitly; Dispose should handle this
// note that by using the using construct, Dispose is called.
}
</NewSnip>

The main reason you should implement IDispose in one of your own classes
is to ensure that unmanaged resources (Database connections is the
classic example) are released.
You might find this template helpful:
<ClassImplementingDispose>
class Billy: IDisposable
{
private bool mDisposed = false;

public void doStuff()
{
// do this in each public method in case user called dispose,
// but then tried to call another method
if ( mDisposed ) throw new ObjectDisposedException();
// do what you normally do.
}

/// <summary>
/// If SupressFinalize wasn't there, the gc would have to do all the
/// extra work that is required for objects in the finalization queue.
/// </summary>
public void Dispose()
{
Dispose( true );
GC.SuppressFinalize(this);
}

protected virtual void Dispose( bool disposing )
{
if ( disposing )
{
// dispose any dependant managed objects if necessary.
// You don't want this to happen when the GC is calling this code
// because you have no idea what state other objects would be in at
that point.
disposed = true;
}
// Free unmanaged resources here.
}

~Billy()
{
Dispose( false );
Debug.Assert(false, "You are using this object improperly. Create in
using construct or ensure to call Dispose()");
}
}
</ClassImplementingDispose>

André wrote:
Thanks Kevin,

Can you help me add the dispose interface?

This is my simple ping class......

Nov 17 '05 #37

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Bob | last post by:
Are there any known applications out there used to test the performance of the .NET garbage collector over a long period of time? Basically I need an application that creates objects, uses them, and...
6
by: Ganesh | last post by:
Is there a utility by microsoft (or anyone) to force garbage collection in a process without have access to the process code. regards Ganesh
11
by: Rick | last post by:
Hi, My question is.. if Lisp, a 40 year old language supports garbage collection, why didn't the authors of C++ choose garbage collection for this language? Are there fundamental reasons behind...
34
by: Ville Voipio | last post by:
I would need to make some high-reliability software running on Linux in an embedded system. Performance (or lack of it) is not an issue, reliability is. The piece of software is rather simple,...
5
by: Bob lazarchik | last post by:
Hello: We are considering developing a time critical system in C#. Our tool used in Semiconductor production and we need to be able to take meaurements at precise 10.0 ms intervals( 1000...
8
by: mike2036 | last post by:
For some reason it appears that garbage collection is releasing an object that I'm still using. The object is declared in a module and instantiated within a class that is in turn instantiated by...
28
by: Goalie_Ca | last post by:
I have been reading (or at least googling) about the potential addition of optional garbage collection to C++0x. There are numerous myths and whatnot with very little detailed information. Will...
56
by: Johnny E. Jensen | last post by:
Hellow I'am not sure what to think about the Garbage Collector. I have a Class OutlookObject, It have two private variables. Private Microsoft.Office.Interop.Outlook.Application _Application =...
350
by: Lloyd Bonafide | last post by:
I followed a link to James Kanze's web site in another thread and was surprised to read this comment by a link to a GC: "I can't imagine writing C++ without it" How many of you c.l.c++'ers use...
158
by: pushpakulkar | last post by:
Hi all, Is garbage collection possible in C++. It doesn't come as part of language support. Is there any specific reason for the same due to the way the language is designed. Or it is...
0
by: DolphinDB | last post by:
The formulas of 101 quantitative trading alphas used by WorldQuant were presented in the paper 101 Formulaic Alphas. However, some formulas are complex, leading to challenges in calculation. Take...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
0
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.