garbage collection

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

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
 
Hi Andre,

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

http://msdn.microsoft.com/library/d...ref/html/frlrfsystemidisposableclasstopic.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.
 
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?
 
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.
 
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;
}
}
}


}
 
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
 
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();
}
}
 
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 said:
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é said:
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;
}
}
}


}
 
Yes, that's fine. Except, you really don't need to set the object
reference to null.
 
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
 
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.
 
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?
 
The Crow said:
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.
 
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/...A6-3647-4070-9F41-A333C6B9181D&displaylang=en

--
HTH,

Kevin Spencer
Microsoft MVP
..Net Developer
Ambiguity has a certain quality to it.
 
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.
}
}
 
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>
 
Willy Denoyette said:
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 said:
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.
 
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
 
Back
Top