2008-11-11 9 views
6

C#을 사용하여 개발중인 응용 프로그램에 대해 버퍼 관리를 개발해야합니다.C#을 사용하는 버퍼 풀 관리

기본적으로 응용 프로그램은 들어올 때 장치에서 메시지를 수신합니다 (짧은 시간 내에 많은 메시지가있을 수 있음). 어떤 종류의 버퍼 풀에 큐를 대기시켜 관리 된 방식으로 처리 할 수 ​​있도록해야합니다.

우리는 256 바이트의 청크 (모든 메시지가 그보다 작습니다)에 메모리 블록을 할당하고 버퍼 풀 관리를 사용하여 수신 메시지 및 버퍼 풀에 사용할 수있는 사용 가능한 버퍼 풀을 확보하려고합니다 처리 할 준비가되었습니다.

그래서 흐름은 "버퍼 확보"(처리) "릴리스 버퍼"또는 "풀에 남겨두기"입니다. 버퍼가 채워지는 시점을 알아야합니다.

잠재적으로 우리는 버퍼를 "들여다보고"풀에서 다음 버퍼를 얻는 것이 아니라 우선 순위가 가장 높은 버퍼를 확인해야합니다.

이미 .NET에서이를 지원합니까? 아니면 사용할 수있는 일부 오픈 소스 코드가 있습니까?

답변

4

C# sharps 메모리 관리는 실제로 매우 효과적이므로 버퍼 풀 대신에 필요한 것을 정확하게 할당하고 큐에 넣을 수 있습니다. 일단 버퍼로 끝내면 가비지 컬렉터가 처리하도록하십시오.

하나의 다른 옵션 (응용 프로그램에 대해 거의 알지 못함)은 메시지를 가져올 때 최소한의 메시지 처리를 수행하고 우선 순위가있는 모든 개체로 전환 한 다음 대기열에서 메시지의 우선 순위를 지정할 수 있습니다. 올바른 속성 또는 메소드 세트를 조사합니다.

최소한의 처리에도 메시지가 너무 빨리 들어오는 경우 2 개의 대기열 시스템을 사용할 수 있습니다. 하나는 처리되지 않은 버퍼의 큐이며 다음 큐는 버퍼에서 빌드 된 메시지 개체의 큐입니다.

나는이 도움이되기를 바랍니다.

+0

좋은 생각이 아닙니다. interop과 관련된 작업을 수행하는 모든 작업은 GC가 객체를 고정해야하기 때문에 조각화 (메모리 부족 예외가 발생합니다)가 발생합니다. –

+2

무엇 사이의 상호 운용성? 실? 응용 프로그램? 프로세스? – grieve

+0

나는 nzpcmad가 P/Invoke가없는 순수한 관리를하고 있다고 생각한다. – user7116

2

왜 메시지를받지 못하고 DeviceMessage 객체를 만들고 그 객체를 Queue에 넣지 않습니까? 우선 순위가 중요하면 DeviceMessage 객체를 큐에 삽입 할 때 DeviceMessage 객체를 우선 순위에 배치하여 자동으로 처리하는 PriorityQueue 클래스를 구현하십시오. 더 많은 OO 접근 방식처럼 보이며 우선 순위에 따라 유지 관리를 간소화합니다.

1

나는 비슷한 것을하고 있습니다. STA 스레드에서 서비스해야하는 MTA 스레드에서 오는 메시지가 있습니다.

BlockingCollection (병렬 fx 확장의 일부)은 여러 STA 스레드 (구성 가능하지만 기본값은 xr * 코어 수)로 모니터링됩니다. 각 스레드는 큐에서 메시지를 팝하려고 시도합니다. 시간이 초과되어 다시 시도하거나 성공적으로 메시지를 띄우고 서비스합니다.

유휴 시간, 작업 길이, 수신 메시지 등을 관리하기 위해 perfmon 카운터와 연결되어있어 큐의 설정을 조정하는 데 사용할 수 있습니다.

큐 항목 우선 순위를 구현하려면 사용자 지정 컬렉션을 구현하거나 BC를 확장해야합니다.

내가 이런 식으로 구현 한 이유 중 하나는 이해할 수 있듯이 queueing theory은 일반적으로 단일 라인, 다중 서버를 선호한다는 것입니다. (왜 나는 그것에 대해 쓰레기를 잡을 것 같습니까?)

2

@grieve : 네트워크는 네이티브입니다. 즉, 버퍼가 네트워크에서 데이터를 수신/전송할 때 메모리에 고정됩니다. 정교에 대한 내 의견을 참조하십시오.

+0

-1, 전 System.Net 네임 스페이스는 최종 사용자가 모든 것을 처리하지 못하도록 추상화한다는 것을 확신합니다. 또한 OP에서 어떤 종류의 interop도 사용하는 응용 프로그램에 대한 언급이 없습니다. – user7116

+1

아마도 명확하지 않습니다. 네트워킹은 항상 관리되지 않는 컨텍스트에서 발생합니다. 즉 네트워크 API에 보내는 버퍼 (네이티브 WINSOCK은 네이티브 WINSOCK에 있습니다.)가 메모리에 고정되어 있습니다. GC가 힙 압축을 시도 할 때 가비지 수집되거나 압축 (메모리에서 이동) 될 수 없습니다. 따라서 대용량 메모리 조각화와 성능 저하는 버퍼가 생성 1 (어쩌면 2 세대까지도)에서 생존 할 수 있고 더 많은 버퍼를 할당하는 동안 GC에 고통이 될 것입니다. –

+0

정확한 방법은 풀을 만드는 것입니다. 네트워크와 함께 사용하기를 원하는 버퍼이므로 메모리는 손실되지만 한 곳에서 응축되어 GC 오버 헤드를 관리하지 않으며 이미 지불 한 메모리 공간에 대한 버퍼를 다시 할당하지 않습니다. 예를 들어, 웹 서버 예제에서 제공하는 캐시를 캐시에두고 메모리에 파일 버퍼를 유지하고 Socket.Send를 사용할 때 이러한 버퍼를 사용하는 것이 좋습니다. - 할당이나 페널티가 없으면 이러한 버퍼는 거의 모든 실제 시나리오에서 오랫동안 유효합니다. –

2

나는 이것이 오래된 게시물이지만, ILNumerics 프로젝트에서 구현 된 메모리 풀을 살펴 봐야한다고 생각한다. 저는 그들이 여러분이 필요로하는 것을 정확히했다고 생각합니다. 그리고 이것은 아주 훌륭한 코드입니다. http://ilnumerics.net/에서 코드를 다운로드하고 ILMemoryPool.cs 파일을 확인하십시오.

+0

ILMemoryPool에 대한 직접 링크 https://ilnumericsnet.svn.sourceforge.net/svnroot/ilnumericsnet/ILNumerics/Misc/ILMemoryPool.cs – Avram