문제

C#로 작성된 TCP 서버가 게시되어 게시물 데이터를 게시합니다. 현재 많은 양의 데이터 (예 : 1GB보다 큰)가 전송되지 않는 한 잘 작동합니다. 메모리가 부족합니다 (메모리에 모든 것을 바이트 배열로 저장합니다 (목록 DTO의 중개자). 큰 파일의 경우 이제 디스크로 스트리밍 한 다음 디스크에서 스트리밍 할 의도로 파일 이름을 전달합니다.

현재 내 모든 루틴은 바이트 어레이를 기대하기 위해 작성되었습니다. 바이트 레이를 메모리 스트림으로 변환하면 메모리 사용이 두 배가됩니까? 메모리 스트림에서 작동하기 위해 코드를 다시 작성하는 것이 디스크에서 스트림을 읽을 때 재사용 할 수 있다고 생각합니까?

어리석은 질문에 대해 죄송합니다. C#이 데이터의 사본을 가져 오거나 참조 할 때 확실하지 않습니다.

도움이 되었습니까?

해결책

당신이 통과하는 경우 byte[] a MemoryStream, 그러면 처음에 데이터를 (생성자에서) 복사하지만 릴리스하는 한 byte[] 쓰레기를 수집 할 수 있습니다. 본질적으로 "두 배가"가 없습니다 (특히 크기를 올바르게 설정하여 시작하여 직접 작성할 수있는 경우 Stream 대신 byte[]).

나는 전적으로 전환한다고 말할 것이다 Stream (하지만 사용 Stream API에서 - Moer 특이한 것은 없습니다. 소비 코드는 어떤 유형을 알 필요가 없습니다). 가장 중요한 것은 사용하도록 선택할 수 있습니다 NetworkStream (소켓에서 직접 읽기) 또는 FileStream (디스크에 버퍼링하려면) 또는 MemoryStream 프로세스를 버퍼하려면. 또한 스트림 기반 코드를 통해 해당 데이터의 양을 읽어야합니다. 반복자 블록 (yield return) LINQ와 마찬가지로 여기에서 매우 도움이 될 수 있습니다. Enumerable 방법 (제외 OrderBy, GroupBy, 등, 어떤 버퍼).

둘 다 지나가지 않습니다 byte[] 전달 a Stream 참조 유형이므로 복사 할 수 있습니다. 복사 한 유일한 것은 참조입니다 (x86/x64에 따라 4 또는 8 바이트).

다른 팁

MemoryStream은 바이트 어레이 주변의 스트림 래퍼이므로 사용하여 아무것도 얻지 못합니다.

최소한 큰 파일의 경우해야 할 일은 파일 스트림을 열고 데이터를 덤프하는 것입니다. 더 낮은 레벨에서 연결에서 x 바이트를 읽은 다음 즉시 파일 스트림에 기록해야합니다. 이런 식으로 당신은 전체 공연을 메모리로 끌어 당기지 않고 한 번에 몇 바이트 만 당기지 않습니다.

이것이 쉽게 수행 할 수 있는지 여부는 TCP 서버가 코딩되는 방식에 따라 다릅니다.

바이트는 값 유형이므로 Ref 키워드없이 함수로 전달하면 매번 사본을 처리하게됩니다. Ref 키워드로 전달하면 원래 바이트 배열을 참조합니다.

MemoryStream은 참조 유형이므로 데이터를 복사하지는 않지만 해당 데이터에 대한 참조를 전달하므로 메모리 사용이 사용시 두 배가되지 않습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top