2012-01-24 6 views
3

나는 이러한 질문이 많음을 알고 있지만 내 특정 상황과 일치하는 것을 볼 수 없습니다.열려있는 파일이 너무 많음 (우분투의 Mono .NET)

우분투의 Mono를 통해 .NET 콘솔 응용 프로그램을 실행하고 있습니다. 응용 프로그램은 서버로 실행되며 TcpListener (TcpListener.AcceptTcpClient())를 통해 연결을 수락합니다. 내가 가진 문제는 잠시 후에 프로그램이 '너무 많은 파일 열기'예외를 던지기 시작한다는 것입니다.

root soft nofile 240000

root hard nofile 320000

는 /etc/security/limits.conf :

은 내가 알고 있는데 두 곳에서 우분투에서 최대 파일 제한을 증가

(해당 프로세스가 루트로 실행 됨)

  • 으로 /etc/sysctl.conf는

fs.file-max = 2000000

모두 ~ 200,000으로 설정됩니다.

시스템에서 열려있는 파일 설명의 수를 확인하면 오류가 발생해도 996 개입니다.

나는 더 많은 연결을 가진 여러 Windows 서버에서 실행되는 동일한 프로그램을 가지고 있으며 결코 이러한 문제가 발생하지 않습니다.

이 오류의 원인은 무엇입니까?

+0

변경 한 구성 파일의 관련 부분을 붙여 넣을 수 있습니까? 응용 프로그램을 실행하는 사용자의 한계가 여전히 기본 1024 인 것처럼 보입니다. 또한 새로운 제한은 내가 알고있는 한 새로운 로그인 후에 만 ​​유효합니다. –

+0

물론, limits.conf는 – antfx

+0

erm .. 무언가가 사라진 것처럼 보입니다. 또한 의견이 아닌 질문을 편집하여 모든 정보를 제공하십시오. 고마워요 :) –

답변

0

Linux에서 TCP 연결에는 파일 핸들이 할당되어 있습니다. 이는 파일 핸들이 너무 많이 표시되는 이유 일 수 있습니다. TCP 연결을 완료 한 후 TCP 연결을 닫고 있습니까? 문제를 나타내는 코드 샘플이 도움이 될 것입니다.

+0

질문을 이해하는 한,이 응용 프로그램은 의도적으로 1024 개 이상의 동시 연결을 사용합니다. –

5

Windows에서 오류가 발생하지 않는 이유는 가비지 수집이 수행 된 것과 관련이있을 수 있습니다. 명시 적으로 소켓 연결을 닫지 않으면 소켓이 수집 될 때 닫힙니다.

이것은 약간의 추측이지만 Mono는 메모리 부족으로 실행될 때까지 가비지 수집을 시작하지 않으며 메모리 소켓이 절대로 실행되지 않을 때까지 소켓을 닫지 않습니다. Windows .NET 프레임 워크는 가비지 수집을 정기적으로 실행하거나 파일 설명자가 부족한 경우 차이점을 설명 할 수 있습니다.

테스트로 일정한 간격으로 수동 가비지 수집 (GB.Collect)을 강제 실행할 수 있으며 오류로 수정되면 적절한 해결책은 닫는 소켓에 대한 가비지 수집에 의존하지 말고 수동으로 닫아야합니다 귀하의 코드입니다. 수동 가비지 콜렉션을 강요하면 문제가 발생합니다.

+0

가비지 수집은 소켓과 어떤 관련이 있습니까? GC는 관리되는 메모리에 관한 것입니다. –

+1

@AndrewBarber GC는 가비지 수집 된 각 클래스의 Finalize() 메서드를 호출합니다. 관리되지 않는 리소스가있는 클래스는 일반적으로 관리되지 않는 핸들을 정리하는 Dispose() 메서드를 추가하여 IDisposable 패턴을 구현합니다. 이러한 클래스의 finalizer는 일반적으로 Dipose() 메서드를 호출합니다. 따라서 사용자가 Dispose를 호출하지 않으면 (매우 나쁜 습관인데) GC가 수집하지 않으면 Dispose가 호출되지 않고 관리되지 않는 리소스가 수집되지 않습니다. – drake7707

+0

@ drake7707 그것은 실제로 좋은 지적이고, 나는 그 코멘트를 게시하는 것이 조금 당황하게 만듭니다! –

0

ulimit를 루트로 설정해 보셨습니까?

일부 배포판에 다음과 같은 작동 할 수 있습니다

확인 ulimit를 :

Command: sudo ulimit -n 
Response: 1024 

설정 ulimit를 :

Command: sudo ulimit -n 65500 

재부팅

확인 ulimit를 :

,685,641,

"Ubuntu Precise"에 대한 자체 테스트에서 Command not found라는 오류가 표시되었습니다. 다음은 나를 위해 일했습니다 http://posidev.com/blog/2009/06/04/set-ulimit-parameters-on-ubuntu/ (와일드 카드가 일반 사용자에게는 작동하지 않을 때 실제 사용자 이름으로 대체하십시오)

+0

매우 중요 - "session required pam_limits.so"를 /etc/pam.d/common-session에 추가하십시오. –

2

나는 처음에 비슷한 문제에 부딪 쳤지 만,

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 

정상적인 사용자 (다른 소프트 한도) 대신 루트에서 프로세스를 실행하고 최대 100,000 개의 연결을 생성 할 수 있도록 관리했습니다. ulimit은 쉘에 바인딩되어 있으므로 모노 (yourapp.exe)를 MonoDevelop가 아닌 ulimit과 동일한 쉘에 입력해야합니다.

OSX 10.7.5에서 실행되는 개발 용.

+0

마누엘의 대답이 저에게 효과적이었습니다. – brendonparker

관련 문제