Jump to content

  • Log In with Google      Sign In   
  • Create Account


help me with memry leak! C#


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
29 replies to this topic

#1 JohnnyCode   Members   -  Reputation: 182

Like
0Likes
Like

Posted 22 May 2012 - 04:27 PM

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.


		   	 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);



client.m_pStream - is a NetworkStream type
client.m_pRHandle - is a IAsyncResult type

Edited by JohnnyCode, 22 May 2012 - 04:27 PM.


Sponsor:

#2 ApochPiQ   Moderators   -  Reputation: 14252

Like
1Likes
Like

Posted 22 May 2012 - 04:30 PM

What makes you think this is a leak? The garbage collector will almost certainly reclaim the memory you're allocating, eventually.

#3 NickUdell   Members   -  Reputation: 288

Like
2Likes
Like

Posted 23 May 2012 - 08:09 AM

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.

#4 JohnnyCode   Members   -  Reputation: 182

Like
0Likes
Like

Posted 23 May 2012 - 08:41 AM

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:

while (m_tcpListener.Pending()) // accept new request

				    {

					    CClient cl = new CClient();



					    cl.m_pConnectionHandle = m_tcpListener.BeginAcceptTcpClient(null, null);

	 	 	 	 ......


and then in my manage thread I finsh attempts like this

 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();

	 	 	 	 .......


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:


 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);



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?

#5 Telastyn   Crossbones+   -  Reputation: 3718

Like
1Likes
Like

Posted 23 May 2012 - 08:48 AM

Are you properly disposing of those streams?

#6 JohnnyCode   Members   -  Reputation: 182

Like
0Likes
Like

Posted 23 May 2012 - 09:05 AM

I allways call client.Release(), this is the definition:


  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;

	    }



but since accepting connections does not leak, and leak is present after those 3 lines of code I guess it is not the issue

#7 Telastyn   Crossbones+   -  Reputation: 3718

Like
1Likes
Like

Posted 23 May 2012 - 09:21 AM

Ugh. Dispose your streams.

#8 JohnnyCode   Members   -  Reputation: 182

Like
0Likes
Like

Posted 23 May 2012 - 09:25 AM

What do you mean by dispose? call Dispose() ?

#9 Telastyn   Crossbones+   -  Reputation: 3718

Like
1Likes
Like

Posted 23 May 2012 - 09:37 AM

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#.

#10 JohnnyCode   Members   -  Reputation: 182

Like
0Likes
Like

Posted 23 May 2012 - 09:54 AM

thanks.

This is my new release function


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;

	    }



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

#11 Telastyn   Crossbones+   -  Reputation: 3718

Like
1Likes
Like

Posted 23 May 2012 - 10:02 AM

There are like 6 streams in there... Disposing one... sigh.

You need to learn. Just slapping together code until something kinda works is the worst kind of programming. Do some research, do some experimentation, extrapolate facts into knowledge.

#12 JohnnyCode   Members   -  Reputation: 182

Like
0Likes
Like

Posted 23 May 2012 - 10:07 AM

Thanks.
Everything except m_pStream and m_pClient is null. This is temporary release function, since I am tracking error, not finalizing code. What might couse memory leak after I read data from m_pStream by these 3 lines of code?

#13 Telastyn   Crossbones+   -  Reputation: 3718

Like
1Likes
Like

Posted 23 May 2012 - 10:15 AM

Nothing in the code you've shown (beyond not disposing of disposable resources of course). Assuming you take the data in the buffer and move it somewhere, that will increase your memory usage, but that's not a leak per se; just normal operating cost.

#14 JohnnyCode   Members   -  Reputation: 182

Like
0Likes
Like

Posted 23 May 2012 - 10:23 AM

you can asssume that code is not leaking, unless I add these 3 instructions

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);



With these lines of code added it leaks.
I am so confused. Why possibly? I would be happy for any suggestion.

#15 ApochPiQ   Moderators   -  Reputation: 14252

Like
1Likes
Like

Posted 23 May 2012 - 11:22 AM

I'm still not sure why you think this is a leak and not just normal operation of the GC?

#16 JohnnyCode   Members   -  Reputation: 182

Like
0Likes
Like

Posted 23 May 2012 - 12:11 PM

You are saying interesting thing apochpiq. Well it is like this.
If I do not use the 3 lines memory stays on 37mb with volatility 10mb, for all time, it does not move to higher values. But if I add the 3 lines, it behaves much more different. Memory keeps growing the way, more time, bigger minimal memory allocated and the volatility is like 10mb. In like 2 hours it is not droping. I have not run out of system mem yet, it will take me too long to achieve that, I will be right back giving you total result of the experiment. Right now for example, I started using delegate callback , memory cummulates from 40mb to 70mb, and when I do not use delegate it cummulates from 40mb to 120 mb. After this I assume I have allocations that are not free to OS and close the app. Using delegates My PC is exhousted with two requests, without delegates about 10 requests per second. But on my i54core I can handle 1000 requests, but trouble is I have 8GB ram there :).

#17 Telastyn   Crossbones+   -  Reputation: 3718

Like
0Likes
Like

Posted 23 May 2012 - 12:15 PM

what delegates?

#18 JohnnyCode   Members   -  Reputation: 182

Like
0Likes
Like

Posted 23 May 2012 - 12:40 PM

the callback delegate for asynchronous calls. But I just tried that, I deffinitely will not use delegates. Ok I am hammering my server for 30 minnutes now and the memory , performing the three lines on connected clients then releasing them, got from 40mb over 30 minnutes to 140mb. I will continue but I believe I am leaking

#19 JohnnyCode   Members   -  Reputation: 182

Like
0Likes
Like

Posted 23 May 2012 - 12:56 PM

memory is now 182mb I am leaking for sure.

#20 Telastyn   Crossbones+   -  Reputation: 3718

Like
1Likes
Like

Posted 23 May 2012 - 01:17 PM

Just post the code. C# code can only really leak memory in 2 ways:
  • You're not disposing disposables.
  • You're creating an object, adding a method from it to an event/delegate and then thinking it will be garbage collected.
Otherwise the memory will increase due to you using it. Anything else is user/measurement error.




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS