2017-10-20 19 views
0

서버 응용 프로그램을 다시 작성하고 응용 프로그램의 메모리 사용에 의문이 생깁니다. 이전 버전은 TcpListener으로 작성되었으며 새 버전은 보통 이전 버전 Socket입니다. 이것은 주로이 질문 및이 문제에 보조되는 성능 및 안정성을위한 것입니다.비동기 소켓 높은 메모리 사용 및 가능한 누수

언급 한 바와 같이 모든 것은 크게 AcceptAsync, SendAsyncReceiveAsync으로 비동기입니다. 또한, AcceptAsync에 대한 초기 킥오프와 다음에 AcceptAsync 대기열 유지, Socket에 다시 쓰도록 처리 한 후 호출 및 연결이 끊어진 클라이언트 정리 등의 유틸리티 작업에는 ThreadPool.QueueUserWorkItem을 사용합니다. 또한 일련의 이벤트가 발생하여 BeginInvokeEndInvoke이 발생합니다.

그 끊어 데이터뿐만 아니라 가용성 메인 드라이버에 대한 검출

는 I가 SocketAsyncEventArgs.BytesTransferredDisconnect 이벤트를 발생 제로 것에 대한 검출뿐만 아니라 ReceiveAsync 봉우리 AvailabilityNotifier 전화 정의 클래스에 의해 처리된다.

응용 프로그램의 처리량이 좋으며 System.Collections.Concurrent 개체의 정상적인 사용으로 인해 거의 0 인 (상대적으로 말하면) 잠금 경합이 있습니다. 그러나 그것은 죽이기에 집착하는 육식 동물처럼 기억에 매달린다.

내부 컬렉션이 지워지고 클라이언트 소켓이 종료 및 처리되고 각 읽기에 대해 새 버퍼를 만드는 대신 버퍼 풀을 활용하는지 디버깅했습니다. 궁극적으로 1,000 개의 연결 (100 동시)을 수행하고 100,000 개의 메시지를 송수신하는 테스트 응용 프로그램을 실행하면 서버 프로세스 메모리가 약 800MB로 확장되고 Windows에서 TIME_WAIT이 발생 했음에도 불구하고 절대로 작동하지 않습니다. 나는 diposal 코드가 ObjectDisposedException 톤과 Null 예외 catch 블럭 덕택에 아래 링크 된 github에서 볼 수 있다는 것을 알고 있습니다.

여기에 github : https://github.com/hoagsie/TcpServer입니다. 게시물에 대해 상당히 길기 때문에 따옴표없이 코드를 말합니다. Program.csClientProgram.cs은 직접 실행하고 싶지만 기본 동작은 NetworkServer.csAvailabilityNotifier.cs입니다. 또한 실행중인 샘플 서버에는 WCF 서비스가 있지만 회신하지 않은 표준 WCF 프로젝트 일뿐입니다. 샘플 시나리오와 일치시키기 위해 방금 필요했습니다.

어떤 수준에서는 중요한지 확실하지 않지만 AnyCPU/x86보다는 x64 모드에서 빌드합니다. 이는 주로 진행될 대상 서버에서 자원을 소비 할 기회를 제공하기위한 것이지만 x86 또는 x64에서이 문제와 관련하여 동작 차이를 발견하지 못했습니다.

는 편집 :

동료는 Visual Studio에서 스냅 샷 도구를 지적했다. 이전에는 이것을 본 적이 없었으며 dotTrace와는 다른 방식으로 표시했습니다. 그것은 의미가있는 SocketAsyncEventArgs 객체 주위에 많은 할당을 지적했지만 건물과 건물은 계속 유지했습니다. 회원 목록을 다시보고 Dispose 메소드를 발견했습니다. 내 문제가 사라졌습니다. 그게 IDisposable 개체라는 것을 몰랐습니다.

답변

0

동료가 Visual Studio의 스냅 샷 도구를 지적했습니다. 이전에는 이것을 본 적이 없었으며 dotTrace와는 다른 방식으로 표시했습니다.그것은 의미가있는 SocketAsyncEventArgs 객체 주위에 많은 할당을 지적했지만 건물과 건물은 계속 유지했습니다. 회원 목록을 다시보고 Dispose 메소드를 발견했습니다. 내 문제가 사라졌습니다. 그게 IDisposable 개체라는 것을 몰랐습니다.