473,385 Members | 1,875 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

Possible bug in .net sockets implementation? Reproducible code inside

At this link I have two c# projects, one is a client, the other is a
server. Just point the ip address of the client at the server

http://www.slip-angle.com/hosted/bug/
The server does little more than the examples in the c# documentation
for how to set up an asynchronous server. It just accepts connections,
reads data into a buffer continously, doing nothing with it.

The client connects 200 sockets, sends some data with each continously,
and occasionally disconnects a socket and reconnects a new one.

Things of note:

1. in this scenario memory increases forever. Not just the private
bytes but the gen2 heap increases forever, even after a forced gen2
garbage collection

2. memory profilers indicate no left behind object references

3.the memory profiler indicates "holes" in the gen2 heap, which can be
caused by "pinned objects". I think perhaps that the data in the
receive buffers is being held onto indefinitely, despite all sockets
being closed on the server.
4. If you change the client to not send any data, the memory will not
increase. If you change the client to not disconnect and reconnect any
sockets, memory will not increase.

If someone can verify if this is a .net bug, or point out my idiocy I
would greatly appreciate it.

Jul 21 '05 #1
14 1821
Some more info:

trying this test with 10 sockets will not lead to memory increase, but
with 50 sockets it will. odd!

Jul 21 '05 #2

"jack" <ja*******@gmail.com> wrote in message
news:11**********************@f14g2000cwb.googlegr oups.com...
At this link I have two c# projects, one is a client, the other is a
server. Just point the ip address of the client at the server

http://www.slip-angle.com/hosted/bug/
The server does little more than the examples in the c# documentation
for how to set up an asynchronous server. It just accepts connections,
reads data into a buffer continously, doing nothing with it.

The client connects 200 sockets, sends some data with each continously,
and occasionally disconnects a socket and reconnects a new one.

Things of note:

1. in this scenario memory increases forever. Not just the private
bytes but the gen2 heap increases forever, even after a forced gen2
garbage collection

2. memory profilers indicate no left behind object references

3.the memory profiler indicates "holes" in the gen2 heap, which can be
caused by "pinned objects". I think perhaps that the data in the
receive buffers is being held onto indefinitely, despite all sockets
being closed on the server.
4. If you change the client to not send any data, the memory will not
increase. If you change the client to not disconnect and reconnect any
sockets, memory will not increase.

If someone can verify if this is a .net bug, or point out my idiocy I
would greatly appreciate it.

No, this is not a bug in the socket library, this relates to the way you
handle your receive buffers and the way your testclient is implemented.
Let me try to explain what happens(I hope I succeed).

You noticed two important things:
1. The Gen2 heap keeps growing, while the number of objects don't.
2. There are holes in the Gen2 heap.

Now if you look at the #Pinned objects perf. counter, you will see there are
a considerable number of them.
These objects are long lived so they end in the Gen2 heap, worse, they end
near the top of the heap, as such preventing a compactation of the heap.
Note that collection is not prevented by this, which explains the ( nearly)
constant # of objects.

Now, why are objects aging into gen2, which objects are these and which are
the pinned objects?
These objects are (1)the MsgState instances, they get instantiated when the
Client connects and they live until the client closes the outgoing socket.
The MsgState contains a reference (2) dataBuffer to a byte[] used as socket
buffer, you know by now that these are pinned for the duration of the
BeginReceive/EndReceive and ProcessMessage sequence. But the problem (lets
call it 'issue1') is that their lifetime is tied to the lifetime of the
MsgState object.
Great, but why are they aging into gen2? This is related to the large number
of objects (sockets) and the way your client is implemented.
Your client creates 200 sockets, sends a (too) small buffer to each of them
in sequence, when done it closes and re-opens one single socket in the
sequence they were created. At that time the Socket (and related objects)
it's MsgState and dataBuffer become eligible for collection. Lets say the GC
kicks in, he won't have a problem to collect the garbage, but heck, he can't
compact the heap (Gen0 to start with) because there are pinned objects at
the top of it preventing reallocation, the result is a (small) hole. After
each GC run, the hole becomes bigger as the same pinned object (your lastly
created socket buffer) prevents compactation.
At some point in time, the Gen0 pointer gets adjusted and becomes the Gen1
pointer and after another number of GC runs the Gen1 pointer becomes the
Gen2 pointer, but at/near the top of it you will always find a (number of)
pinned object.

Ok, how to solve this?
1. In ProcessMessage, you should move the contents of the (pinned) receive
buffer to another buffer and release the buffer (re-create a new instance).
This will shorten the period the buffer is pinned, so it won't end as an
aged object.
2. You should change your test method (or at least your message sending
algorithm), I understand that you are trying to simulate a large number of
clients, but this is not the right way of doing. You need separate client
machines, and each one must run a number of processes and each process must
consist of a number of threads each accessing a single socket.

Another remark is that you are touching the UI from thread pool threads,
this is a definitive no no in windows, you have to marshal the call sing
Control.Invoke.

Willy.



Jul 21 '05 #3
Thanks, I will try moving the contents of the buffer and recreating it
see if that does the trick (though I think I used to do it that way
with the same problem).

As for my test method, I wrote that test to simulate what is actually
happening on our live server, and it is causing the same result.

Jul 21 '05 #4
Well, making copies of the msgstate and freeing up the old one seems to
have done the trick with my test case.

Very interesting. I obviously need to read up more on how the
compacting process works in .net

Jul 21 '05 #5

"jack" <ja*******@gmail.com> wrote in message
news:11*********************@g14g2000cwa.googlegro ups.com...
Thanks, I will try moving the contents of the buffer and recreating it
see if that does the trick (though I think I used to do it that way
with the same problem).

As for my test method, I wrote that test to simulate what is actually
happening on our live server, and it is causing the same result.


No, that alone won't do the trick, you also have to change the clients test
algorithm, make it asynchronous too, and use a number of multithreaded
clients handling a single or a limited number of sockets per thread.
Both issues are related, not releasing the buffers at EndReceiveData keep
them pinned for the duration of the connection, but that's only part of the
problem. Creating that large number of sockets in sequence followed by
sending data in the same sequence will result in a lot of aged/pinned
objects at the server.
Don't forget that the way you did, it takes 400 seconds before each socket
has received it's 200 messages and gets closed.

I'm also not clear on why you send such small buffers (only 6 bytes per
send), this is a very inefficient way of data transfer over TCP sockets

Willy.
Jul 21 '05 #6
I'm simulating what will happen on our live server. Clients will
connect (a few hundred of them) occasionally send a small bit of data,
and disconnect after a while. These clients are out there in the
population so I have to deal with them somehow.

Jul 21 '05 #7

"jack" <ja*******@gmail.com> wrote in message
news:11*********************@o13g2000cwo.googlegro ups.com...
I'm simulating what will happen on our live server. Clients will
connect (a few hundred of them) occasionally send a small bit of data,
and disconnect after a while. These clients are out there in the
population so I have to deal with them somehow.


Jack,

I understand, but IMO it's not very realistic (not impossible) that a client
waits 2 seconds after a connect request before sending part of the data,
wait again 2 seconds and wait... etc. and finaly need 6 minutes to send 1200
bytes to a server. Wouldn't it be better to collect the data at the client
and send it in one go?

Just my 2c.
Willy.
Jul 21 '05 #8
The clients allow realtime human interaction (chat, forwarding browser
events etc). If the user wants to send a short chat message every few
seconds, or send scroll events in realtime from time to time, that is
what they will do. And they might be in a session for an hour or more.

Jul 21 '05 #9
Anyone else care to comment?

It seems kind of ridiculous that dot net can't support behavior like
this?

How would one go about writing a large scale server that deals with
realtime input from users that come and go?

Jul 21 '05 #10

"jack" <ja*******@gmail.com> wrote in message
news:11**********************@o13g2000cwo.googlegr oups.com...
Anyone else care to comment?

It seems kind of ridiculous that dot net can't support behavior like
this?

How would one go about writing a large scale server that deals with
realtime input from users that come and go?


What do you mean, I thought this was solved by copying your message state.

Willy.
Jul 21 '05 #11
Jack,

You are using a solution from the beginning of Internet.

Ever thought of using a webservice. That makes you less dependend from all
kinds of hardware.

Just my thought,

Cor
Jul 21 '05 #12
We have thought about it, thought I'm not sure how well that would work
with realtime interactions that have to go both directions (clients
pushing to server and server pushing to clients).

Willy, copying the message states made my test case stop growing
memory, but not our real production server.

I did just this morning come up with a solution that seems to have done
the trick.

I made a pool of message states. Grab one from the pool as sockets
connect, put them back as they disconnect.

Jul 21 '05 #13

"jack" <ja*******@gmail.com> wrote in message
news:11**********************@f14g2000cwb.googlegr oups.com...
We have thought about it, thought I'm not sure how well that would work
with realtime interactions that have to go both directions (clients
pushing to server and server pushing to clients).

Willy, copying the message states made my test case stop growing
memory, but not our real production server.

I did just this morning come up with a solution that seems to have done
the trick.

I made a pool of message states. Grab one from the pool as sockets
connect, put them back as they disconnect.


Great, I have written a similar test case as yours, the only thing I did is
make sure that the pinned IO buffers are decoupled from the state objects.
I'm actually running this code on a server (W2K3) with 2000 sockets
connected over a real network (not the loopback interface), managed heap
consumption seems stable until now.

Willy.
Jul 21 '05 #14
If you are curious to see what I've been working on, you can check it
out here:

www.jybe.com

Thanks for your assistance!

Jul 21 '05 #15

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Tero Saarni | last post by:
Hi, I have several threads communicating with each other using events stored in Queues. Threads block on Queue.get() until somebody publishes an event in thread's event queue. I need to add...
1
by: Tim Black | last post by:
My application requires sending a large piece (~2MB) of data to several devices on a network via TCP sockets. I have experimented with different methods for doing this and this has raised some...
3
by: David | last post by:
Hi, Ive been trying to work this out for the past 2 days now and im not getting anywhere fast. The problem i have is that i am using Asynchronous sockets to create a Socket Client library....
3
by: Michael Maercker | last post by:
hi! i'm really not into networking at all and have now been asigned the task of porting a vb6-code into vb.net (compact framework, in this case) and the code uses the winsock-control. i quickly...
21
by: jack | last post by:
At this link I have two c# projects, one is a client, the other is a server. Just point the ip address of the client at the server http://www.slip-angle.com/hosted/bug/ The server does...
0
by: Grant Wickman | last post by:
Our team has just fixed a really nasty problem that appears to be caused by an obscure bug in the sort method of Arraylist and daisy-chained webservice stubs. We've fixed the bug so I'll not...
3
by: Daniel | last post by:
Hello, I can't seem to get my sockets code to work right. Here is what I have inside my RequestHandler handle() function: total_data= data = True...
13
by: Alexander Gnauck | last post by:
Hello, while using async sockets I ran into a strange problem which occurs only on some machines. I wrote a small demo application which can be used to reproduce the problem. You can download it...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.