I know there are a lot of these questions on SO but I cannot see anything that matches my specific situation.
I am running a .NET console application via Mono on Ubuntu. The app runs as a server and accepts connections via a TcpListener (TcpListener.AcceptTcpClient()). The problem I have is that after a while the program starts throwing 'Too many open files' exceptions.
I have increased the max file limit in Ubuntu in the two places that I am aware of:
root soft nofile 240000
root hard nofile 320000
(The process in question runs as root)
fs.file-max = 2000000
Both are set to ~200000.
If check the number of open file descriptions on the system it is only 996 even though it is throwing the errors.
I have the same program running on several Windows servers with many more connections and they never have this problem.
Any idea what could be causing this error?
The Too many open files message occurs on UNIX and Linux® operating systems. The default setting for the maximum number of open files might be too low. To avoid this condition, increase the maximum open files to 8000 : Edit the /etc/security/limit.
The reason the error does not occur on Windows could be related to when garbage collection is done. If you do not explicitly close your socket connections, the sockets will be closed when they are collected.
This is somewhat speculative but if Mono does not start the garbage collection until it sees you running out of memory and it never runs out of memory sockets are never closed. Windows .NET framework might run garbage collecting regularly or when it sees you running out of file descriptors, which could account for the difference.
As a test you could force a manual garbage collection (GB.Collect) at regular intervals and if this fixes your errors, the proper solution would be to not rely on garbage collection for closing sockets, making sure to close them manually in your code. Forcing manual garbage collection brings its own set of problems.
I first ran into a similar problem, but this is what I did to get it working:
sysctl -w net.inet.ip.portrange.first=3000
sysctl -w net.inet.ip.portrange.hifirst=3000
sysctl -w kern.maxfiles=900000
sysctl -w kern.maxfilesperproc=900000
ulimit -n 900000
I ran the process under root instead of a normal user (different soft limit) and managed to create up to 100,000 connections. Note that ulimit is bound to a shell, so need to enter the mono (yourapp.exe) in the same shell as you do the ulimit, not from MonoDevelop.
For development running under OSX 10.7.5.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With