打开的文件太多(Ubuntu上的Mono .NET)

时间:2012-01-24 14:45:13

标签: c# .net ubuntu mono

我知道这些问题很多,但我看不到任何符合我具体情况的内容。

我在Ubuntu上通过Mono运行.NET控制台应用程序。该应用程序作为服务器运行,并通过TcpListener(TcpListener.AcceptTcpClient())接受连接。我遇到的问题是,一段时间后程序开始抛出“太多打开文件”的异常。

我已经在我知道的两个地方增加了Ubuntu中的最大文件限制:

  • /etc/security/limits.conf文件

root soft nofile 240000

root hard nofile 320000

(相关流程以root身份运行)

  • /etc/sysctl.conf中

fs.file-max = 2000000

两者都设置为~200000。

如果检查系统上的打开文件描述的数量,它只有996,即使它丢失了错误。

我在几台Windows服务器上运行的程序相同,连接次数多,而且从来没有这个问题。

知道可能导致此错误的原因是什么?

4 个答案:

答案 0 :(得分:6)

Windows上不发生错误的原因可能与垃圾收集完成时有关。如果未明确关闭套接字连接,则在收集套接字时将关闭套接字。

这有点推测但是如果Mono没有启动垃圾收集,直到它看到你的内存不足并且它永远不会耗尽内存套接字永远不会关闭。 Windows .NET框架可能会定期运行垃圾收集,或者当它看到文件描述符用尽时,这可能会导致差异。

作为测试,您可以定期强制进行手动垃圾回收(GB.Collect),如果这样可以解决您的错误,那么正确的解决方案就是不要依赖垃圾回收来关闭套接字,确保手动关闭它们。你的代码。强制手动垃圾收集会带来一系列问题。

答案 1 :(得分:3)

我首先遇到了类似的问题,但这就是我为了让它发挥作用而做的事情:

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  

我在root下运行该进程而不是普通用户(不同的软限制),并设法创建多达100,000个连接。请注意,ulimit绑定到shell,因此需要在与执行ulimit相同的shell中输入mono(yourapp.exe),而不是从MonoDevelop中输入。

对于在OSX 10.7.5下运行的开发。

答案 2 :(得分:0)

在linux中,TCP连接被分配了一个文件句柄,这可能是它显示太多打开文件句柄的原因。完成后,您是否关闭了TCP连接?展示问题的代码示例会有所帮助。

答案 3 :(得分:0)

您是否尝试过以root身份设置ulimit?

在某些发行版中,以下内容可能有效:

检查ulimit:

Command: sudo ulimit -n
Response: 1024

设置ulimit:

Command: sudo ulimit -n 65500

重新启动

检查ulimit:

Command: sudo ulimit -n
Response: 65500

我自己在“Ubuntu Precise”上的测试返回了一个错误,指出找不到命令。 以下但是对我来说http://posidev.com/blog/2009/06/04/set-ulimit-parameters-on-ubuntu/(当通配符对普通用户不起作用时,用实际用户名替换“user”)