Jump to content

  • Log In with Google      Sign In   
  • Create Account

FREE SOFTWARE GIVEAWAY

We have 4 x Pro Licences (valued at $59 each) for 2d modular animation software Spriter to give away in this Thursday's GDNet Direct email newsletter.


Read more in this forum topic or make sure you're signed up (from the right-hand sidebar on the homepage) and read Thursday's newsletter to get in the running!


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

#21 JohnnyCode   Members   -  Reputation: 311

Like
0Likes
Like

Posted 23 May 2012 - 03:58 PM

As I have mentioned, the code does not leak unless those three lines are added, but you are right, here is the code:
the aplication starts two threads: this is body of thread one

	    void ListenToRequestsForward()

	    {

		    m_tcpListener.Start(40000);

		    if (!m_bIsBalancer)

		    {

			    m_tcpForwardListener.Start(40000);

			    m_tcpSecureListener.Start(40000);

		    }

		   

		  

		    while (m_bHttpServiceRunning)

		    {

			    LinkedListNode<CClient> nd = m_aClients.First;

			    try

			    {



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

				    {

					    CClient cl = new CClient();

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





					    cl.m_iTimeOfConnection = System.Environment.TickCount;

					    cl.m_cTimeOfConnection = DateTime.Now.TimeOfDay;

					   

					    cl.m_cTimeOfConnection = DateTime.Now.TimeOfDay;



					    {

						    m_aClients.AddLast(cl);

					    }

					    

				    }

				    if (!m_bIsBalancer)

				    while (m_tcpSecureListener.Pending())

				    {

					    CClient cl = new CClient();

					    cl.m_bSecure = true;



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



					    cl.m_cTimeOfConnection = DateTime.Now.TimeOfDay;







					    {

						    m_aClients.AddLast(cl);

					    }

				    }

			    if (!m_bIsBalancer)

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

				    {

					    CClient cl = new CClient();



		    

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



					    cl.m_cTimeOfConnection = DateTime.Now.TimeOfDay;



					    

					    {

						    m_aClients.AddLast(cl);

					    }

				    }

			    }

			    catch (Exception e)

			    {



			    }

			    if (!m_bIsBalancer)

				    Thread.Sleep(10);

			  

			    lock (m_aClients)

			    {

				    while (nd != null)

				    {

					    LinkedListNode<CClient> next = nd.Next;

					    CClient fclient = (CClient)nd.Value;

					    nd = next;



					    if (fclient.m_bIsFree)

						    m_aClients.Remove(fclient);

				    }

			    }

		    }

		    try

		    {

			    m_tcpForwardListener.Stop();

			    m_tcpListener.Stop();

			    m_tcpSecureListener.Stop();

		    }

		    catch{}

		   

	    }


this is a listen thread
Here is much more complicated manage thread

	    void ManageConnections()

	    {

		    // serve current requests

		    while (m_bHttpServiceRunning)

		    {

			   

			    LinkedListNode<CClient> nd = m_aClients.First;

			    lock (m_aClients)

			    {

				    while (nd != null)

				    {

					    LinkedListNode<CClient> next = nd.Next;

					    CClient fclient = (CClient)nd.Value;

					    nd = next;

					    try

					    {

						    if (fclient.m_bSecure)

						    {

							    // process streaming as secure SSL

							    if (!fclient.m_bIsFree)

								    SSL_FinishConnectionAttempt(fclient);

							    if (!fclient.m_bIsFree)

								    SSL_ReadRequest(fclient);

							    if (!fclient.m_bIsFree)

								    SSL_ServeRequest(fclient);

							    if (!fclient.m_bIsFree)

								    SSL_ReturnRequest(fclient);

						    }

						    else

						    {

							    // process http protocol

							   

							    if (!fclient.m_bIsFree)

								    F_FinishConnectionAttempt(fclient);

							    if (!fclient.m_bIsFree)

								    F_ReadRequest(fclient);

							    if (!fclient.m_bIsFree)

								    F_ServeRequest(fclient);

							     

							    if (!fclient.m_bIsFree)

								    F_ReturnRequest(fclient);

						    }



					    }

					    catch (Exception e)

					    {

						    fclient.Release();

					    }

				    }

			    }

				  

		    }



	    }


From now on, only F_FinishConnectionAttempt() and F_ReadRequest() functions are run, beacouse in read function I perform only these 3 lines and release client,

this is F_FinishConnectionAttempt() function

 void   F_FinishConnectionAttempt(CClient fclient)

	    {

		    if (fclient.m_bConnected)

		    {

			    return;

		    }

		    else

		    {

			    if (fclient.m_pConnectionHandle.IsCompleted)

			    {

				    fclient.m_bConnected = true;

				    fclient.m_pClient = m_tcpListener.EndAcceptTcpClient(fclient.m_pConnectionHandle);

				    IPEndPoint ep = (IPEndPoint)fclient.m_pClient.Client.RemoteEndPoint;

				    fclient.m_sPublicIP = ep.Address.ToString();

				    fclient.port = ep.Port;

				    // check for amount of ips of the client being served



				    int amount = CheckClientForAmountOfIPsInTheStack(fclient);

				    if (amount >= m_iMaxOfConnectionsForanIP)

				    {

					    fclient.Release();

					    //m_aClients.Remove(fclient);

					    return;

				    }

				    fclient.m_pStream = fclient.m_pClient.GetStream();



			    }

		    }

	    }


And now F_ReadRequest()

	 void F_ReadRequest(CClient client)

		 {

			 if (DateTime.Now.TimeOfDay - client.m_cTimeOfConnection > m_cMaxConnectionDuration)

			 {

				  {

						 client.Release();

						 return;

					 }

			    

			 }

			 if (!client.m_bConnected)

				 return;



		   





			 if (client.m_bRecieveComplete == true)

				 return;

		     

			 // start to read request

			 if (client.m_pRHandle == null) // have not started receiving bytes

			 {

				 //client.Release(); return; // if I uncomment this line no leak is performed



				 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.Release(); return;





			 }

			 else

			 {

				 //................ this never runs





Sponsor:

#22 Telastyn   Crossbones+   -  Reputation: 3730

Like
1Likes
Like

Posted 23 May 2012 - 05:37 PM

Ugh, what a mess...

At the very least you're not disposing of TcpClients when accepting new ones. And there's a pile of streams not being disposed of properly even if Release does what it is supposed to. Can you do a plain old blocking read rather than BeginRead? I suspect the callback is required, but haven't ever used the asynchronous stuff.

#23 JohnnyCode   Members   -  Reputation: 311

Like
0Likes
Like

Posted 24 May 2012 - 09:27 AM

Ugh, what a mess...

At the very least you're not disposing of TcpClients when accepting new ones.


F_FinishConnectionAttempt() assigns TcpClient exactly once, as this whole routine must be performed exactly once for program to be functional.

And there's a pile of streams not being disposed of properly even if Release does what it is supposed to. Can you do a plain old blocking read rather than BeginRead? I suspect the callback is required, but haven't ever used the asynchronous stuff.

The Release function is not cousing the leak for sure, those other streams are not created in this leak studying scenario, msdn also says that NetworkStream.Close() calls Dispose() function. I am gonna try synchronous read about theese 3 lines as you suggested to investigate this further.

What I am starting to believe is that native objects allocated by NetworkStream class are not freed to OS somehow. Using delegates leaks too. I am not going that way but I have tried it. I am gona replace theese 3 lines with synchronous read like this:
 byte[] buff = new byte[4000];
				 client.m_pStream.Read(buff, 0, 4000);
			   client.Release(); return;


#24 Mike.Popoloski   Crossbones+   -  Reputation: 2931

Like
2Likes
Like

Posted 24 May 2012 - 09:38 AM

Once you start randomly assuming that core platform and OS components are broken, you've lost all chance you had at solving the problem rationally. At this point you might as well start banging on the keyboard and hoping that it all works out in the end.

Using delegates leaks too


I mean, really? Come on now. An integral feature of popular and widely used runtime leaks huge amounts of memory? What are the odds of that?
Mike Popoloski | Journal | SlimDX

#25 JohnnyCode   Members   -  Reputation: 311

Like
-1Likes
Like

Posted 24 May 2012 - 09:55 AM

so with synchronous read it is not leaking for sure. If instead I use

 byte[] buff = new byte[40000];

				 client.m_pRHandle = client.m_pStream.BeginRead(buff, 0, 4000, null, null);

				 int redbytes = client.m_pStream.EndRead(client.m_pRHandle);

			     

			   client.Release(); return;


It leaks.

Really

#26 JohnnyCode   Members   -  Reputation: 311

Like
-1Likes
Like

Posted 24 May 2012 - 10:01 AM

Once you start randomly assuming that core platform and OS components are broken, you've lost all chance you had at solving the problem rationally. At this point you might as well start banging on the keyboard and hoping that it all works out in the end.


I admitt. I am really thinking for wraping c++ winsocks on my own to C#. About the delegates. I do not need to assign a static function that runs as a thread and extract my data there, I tried: 100 CPU load and slow, can handle few times less requests, I admit I was performance unsmart when doing it but still it should not happen to such extend.

#27 JohnnyCode   Members   -  Reputation: 311

Like
0Likes
Like

Posted 24 May 2012 - 10:12 AM

please , help, any suggestion can save me.

#28 JohnnyCode   Members   -  Reputation: 311

Like
0Likes
Like

Posted 24 May 2012 - 12:46 PM

I really didn't mean to be unpolite, I am sorry if I sounded so. Thank you all for help. I am not trolling guys, I am realy facing this problem I described. It is unbelievable even for me as I do not know what to inspect in the three lines that makes my project leak if I add them to it. I realy perform no other change.

#29 Telastyn   Crossbones+   -  Reputation: 3730

Like
1Likes
Like

Posted 24 May 2012 - 01:27 PM

Sorry, I am not that familiar with the async stuff. How is the synchronous read insufficient again?

#30 JohnnyCode   Members   -  Reputation: 311

Like
0Likes
Like

Posted 24 May 2012 - 02:53 PM

synchronous read performs absolutely correctly.
I have studied something about socket communication and what I have found out is:- asynchronous calls are a derivation of synchronous calls (I have thought otherwise formely). Synchronous calls are much more native to hardware than asynchronous one. Asynchronous call in fact calls synchronous read in a separate thread- this loads no cpu time as synchronous read performs away hardware routine on the net device and returns the data.

So I saved myself from wraping socket c++ library by manualy creating thread that contains only synchronous read on a stream. It blocks, takes time, but do not use cpu at all. I am totaly happy with this. Here is the class that I migrated the whole project in a minute to:








    public class CNetworkStream

    {

	    private NetworkStream m_pStream = null;

	    public CNetworkStream(NetworkStream stream)

	    {

		    m_pStream=stream;

	    }

	    public CAsyncResult BeginRead(byte[] buff,int offset,int count,object n1,object n2)

	    {

		    CAsyncResult res = new CAsyncResult();

		    res.offset = offset;

		    res.buff = buff;

		    res.count = count;

		    res.m_pStream = m_pStream;

		    Thread readthread = new Thread(ReadInThread);

		    readthread.Start(res);

		    return res;

	    }

	    public int EndRead(CAsyncResult what)

	    {

		    while (!what.IsCompleted) ;



		    return what.redbytes;

	    }

	    private static void ReadInThread(object data)

	    {

		    CAsyncResult res = (CAsyncResult)data;

		    int red = 0;



		    try { red = res.m_pStream.Read(res.buff, res.offset, res.count); }

		    //catch (Exception e) { res.IsCompleted = true; throw e; }

		    catch{}

		    res.redbytes = red;

		    res.IsCompleted = true;

	    }





	    ////////////write

	    public CAsyncResult BeginWrite(byte[] buff, int offset, int count,object n1,object n2)

	    {

		    CAsyncResult res = new CAsyncResult();

		    res.offset = offset;

		    res.buff = buff;

		    res.count = count;

		    res.m_pStream = m_pStream;

		    Thread readthread = new Thread(WriteInThread);

		    readthread.Start(res);

		    return res;

	    }

	    public void EndWrite(CAsyncResult what)

	    {

		    while (!what.IsCompleted) ;



	    }

	    private static void WriteInThread(object data)

	    {

		    CAsyncResult res = (CAsyncResult)data;



		    try { res.m_pStream.Write(res.buff, res.offset, res.count); }

		    //catch (Exception e) { res.IsCompleted = true; throw e; }

		    catch { }

		    res.IsCompleted = true;

	    }

	    public void Close()

	    {

		    m_pStream.Close();

	    }

    }





 public class CAsyncResult

    {

	    public bool IsCompleted = false;

	    public int redbytes = 0;

	    public NetworkStream m_pStream;



	    public byte[] buff;

	    public int offset;

	    public int count;

    };







I know there are weak design parts, but it serves my purpose greatly.




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