• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
JohnnyCode

help me with memry leak! C#

29 posts in this topic

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 Edited by JohnnyCode
0

Share this post


Link to post
Share on other sites
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
2

Share this post


Link to post
Share on other sites
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?
0

Share this post


Link to post
Share on other sites
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
0

Share this post


Link to post
Share on other sites
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 [url="http://msdn.microsoft.com/en-us/library/fs2xkftw.aspx"]implement IDisposable yourself[/url] 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#.
1

Share this post


Link to post
Share on other sites
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.
0

Share this post


Link to post
Share on other sites
There are like 6 streams in there... Disposing one... sigh.

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

Share this post


Link to post
Share on other sites
Thanks.
[font=arial,helvetica,sans-serif]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?[/font]
0

Share this post


Link to post
Share on other sites
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.
1

Share this post


Link to post
Share on other sites
you can asssume that code is not leaking, unless I add these 3 instructions
[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]

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

Share this post


Link to post
Share on other sites
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 :).
0

Share this post


Link to post
Share on other sites
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
0

Share this post


Link to post
Share on other sites
Just post the code. C# code can only really leak memory in 2 ways:
[list=1]
[*]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.
[/list]
Otherwise the memory will increase due to you using it. Anything else is user/measurement error.
1

Share this post


Link to post
Share on other sites
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
[source]
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{}

}
[/source]
this is a listen thread
Here is much more complicated manage thread
[source]
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();
}
}
}

}

}
[/source]
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
[source]
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();

}
}
}
[/source]
And now F_ReadRequest()
[source]
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

[/source]
0

Share this post


Link to post
Share on other sites
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.
1

Share this post


Link to post
Share on other sites
[quote name='Telastyn' timestamp='1337816270' post='4942727']
Ugh, what a mess...

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

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

[quote] 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.
[/quote]
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:
[source]
byte[] buff = new byte[4000];
client.m_pStream.Read(buff, 0, 4000);
client.Release(); return;
[/source]
0

Share this post


Link to post
Share on other sites
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.

[quote]
Using delegates leaks too
[/quote]

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?
2

Share this post


Link to post
Share on other sites
so with synchronous read it is not leaking for sure. If instead I use
[source]
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;
[/source]
It leaks.

Really
-1

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0