help me with memry leak! C#

Started by
28 comments, last by JohnnyCode 11 years, 11 months ago
hi all,

I have this memory consumption leak,
I have a code that is repeated over and over, it couses no memory run out and is constant about memory, but if I add following instructions to this correct code, allocated memory just gets bigger and bigger. This is the instruction that couses the code to leak when added to.

[source]
byte[] buff = new byte[4000];
client.m_pRHandle = client.m_pStream.BeginRead(buff, 0, 4000, null, null);
int redbytes = client.m_pStream.EndRead(client.m_pRHandle);
[/source]

client.m_pStream - is a NetworkStream type
client.m_pRHandle - is a IAsyncResult type
Advertisement
What makes you think this is a leak? The garbage collector will almost certainly reclaim the memory you're allocating, eventually.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

We're gonna need to see a bit more code than what you've given us there. Does it happen inside a loop? If so show us the loop too, does it happen inside a function? Show us the function. We'll at least need to see where you create your NetworkStream and what is sending the IAsyncResult.

Also what is this code meant to do?

Looks like you're trying to work out how many bytes you can read in between instructions? I'm not sure you fully understand asynchronous callbacks there. You're getting a handle to the async result, but you're then immediately ending the read. There's no way you can be sure it's going to have read anything in that time. It looks like you're writing synchonous code and expecting it to work asynchronously.

So to summarize:

Tell us what the code is meant to do
Comment it, for the love of god comment it.
Give us more of the code so we can actually see where memory is being allocated or deallocated and how quickly
Sole Creator of Pigment - a procedural, block-base space trading sim.

PhD student working on medical imaging at the University of Southampton.

Enjoyer of games, films, books and cider.
Hi, thanks so far.

Well thing is I know it is not reasonable to call EndRead right after BeginRead since I will have to wait, but I have tried to track down the memory leak in my rather large application, and when I reduced application to only read data, it was still leaking, but when I reduced the aplication to even not make one asynchronus call except accepting connections it does not leak. With only accpeting connections and this 3line code I posted, it leaks, withou it, it does not.
This is how I accept connections:
[source]
while (m_tcpListener.Pending()) // accept new request
{
CClient cl = new CClient();

cl.m_pConnectionHandle = m_tcpListener.BeginAcceptTcpClient(null, null);
......
[/source]
and then in my manage thread I finsh attempts like this
[source]
if (fclient.m_pConnectionHandle.IsCompleted)
{
fclient.m_bConnected = true;
fclient.m_pClient = m_tcpListener.EndAcceptTcpClient(fclient.m_pConnectionHandle);
fclient.m_pStream = fclient.m_pClient.GetStream();
.......
[/source]
So far, this works withou memory loosing over time , when many connections are fired on my server.
But, if for each such connected client I add this single operation before I release it:

[source]
byte[] buff = new byte[4000];
client.m_pRHandle = client.m_pStream.BeginRead(buff, 0, 4000, null, null);
int redbytes = client.m_pStream.EndRead(client.m_pRHandle);
[/source]

memory grows permanently. I keep no reference to buff or so, theese are the only lines I add for real.
As Apochpiq has mentioned, I believe that I realy leak memory, I have run server for hour and it got from 32mb to like 128mb. Can GC perform like this?
Are you properly disposing of those streams?
I allways call client.Release(), this is the definition:

[source]
public void Release()
{

try { m_pForwardClient.Close(); }
catch { }
try { m_pForwardStream.Close(); }
catch { }
try { m_pClient.Close(); }
catch { }
try { m_pStream.Close(); }
catch { }
try { m_pResponseObject.m_pRequestedFileStream.Close(); }
catch { }
try { m_pResponseObject.OutputStream.Close(); }
catch { }
try { m_pSecureStream.Close(); }
catch { }
m_bIsFree = true;
}
[/source]

but since accepting connections does not leak, and leak is present after those 3 lines of code I guess it is not the issue
Ugh. Dispose your streams.
What do you mean by dispose? call Dispose() ?
Yes, though this is a basic element to C# programming... Releasing resources is done via the IDisposable interface. The using block is best used for this, and for your class you'll likely want to implement IDisposable yourself in such a way that it disposes of its components. Not disposing of resources properly is one of the few ways it's even possible to leak memory in C#.
thanks.

This is my new release function

[source]
public void Release()
{

try { m_pForwardClient.Close(); }
catch { }
try { m_pForwardStream.Close(); }
catch { }
try { m_pClient.Close(); }
catch { }
try { m_pStream.Close(); }
catch { }
try { m_pStream.Dispose(); }
catch { }
try { m_pResponseObject.m_pRequestedFileStream.Close(); }
catch { }
try { m_pResponseObject.OutputStream.Close(); }
catch { }
try { m_pSecureStream.Close(); }
catch { }
m_bIsFree = true;
}
[/source]

I use only m_pStream. It still accumulates memory after I read data from the stream.

This topic is closed to new replies.

Advertisement