서버 응용 프로그램을 다시 작성하고 응용 프로그램의 메모리 사용에 의문이 생깁니다. 이전 버전은 TcpListener
으로 작성되었으며 새 버전은 보통 이전 버전 Socket
입니다. 이것은 주로이 질문 및이 문제에 보조되는 성능 및 안정성을위한 것입니다.비동기 소켓 높은 메모리 사용 및 가능한 누수
언급 한 바와 같이 모든 것은 크게 AcceptAsync
, SendAsync
및 ReceiveAsync
으로 비동기입니다. 또한, AcceptAsync
에 대한 초기 킥오프와 다음에 AcceptAsync
대기열 유지, Socket
에 다시 쓰도록 처리 한 후 호출 및 연결이 끊어진 클라이언트 정리 등의 유틸리티 작업에는 ThreadPool.QueueUserWorkItem
을 사용합니다. 또한 일련의 이벤트가 발생하여 BeginInvoke
및 EndInvoke
이 발생합니다.
그 끊어 데이터뿐만 아니라 가용성 메인 드라이버에 대한 검출
는 I가SocketAsyncEventArgs.BytesTransferred
가
Disconnect
이벤트를 발생 제로 것에 대한 검출뿐만 아니라
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.cs
과 ClientProgram.cs
은 직접 실행하고 싶지만 기본 동작은 NetworkServer.cs
과 AvailabilityNotifier.cs
입니다. 또한 실행중인 샘플 서버에는 WCF 서비스가 있지만 회신하지 않은 표준 WCF 프로젝트 일뿐입니다. 샘플 시나리오와 일치시키기 위해 방금 필요했습니다.
어떤 수준에서는 중요한지 확실하지 않지만 AnyCPU/x86보다는 x64 모드에서 빌드합니다. 이는 주로 진행될 대상 서버에서 자원을 소비 할 기회를 제공하기위한 것이지만 x86 또는 x64에서이 문제와 관련하여 동작 차이를 발견하지 못했습니다.
는 편집 :
동료는 Visual Studio에서 스냅 샷 도구를 지적했다. 이전에는 이것을 본 적이 없었으며 dotTrace와는 다른 방식으로 표시했습니다. 그것은 의미가있는 SocketAsyncEventArgs
객체 주위에 많은 할당을 지적했지만 건물과 건물은 계속 유지했습니다. 회원 목록을 다시보고 Dispose
메소드를 발견했습니다. 내 문제가 사라졌습니다. 그게 IDisposable
개체라는 것을 몰랐습니다.