문제

수천 개의 작은 버퍼 (각각 16-30 바이트)를 무작위 위치에 거대한 파일에 쓰는 10 개의 스레드가 있습니다. 일부 스레드는 filestream.write () opreceation에서 unfmemoryException을 던집니다.

OutofMemoryException의 원인은 무엇입니까? 무엇을 찾아야합니까?

나는 다음과 같은 파일 스트림을 사용하고 있습니다 (모든 서면 항목에 대해 -이 코드는 10 개의 다른 스레드에서 실행됩니다) :

using (FileStream fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite, BigBufferSizeInBytes, FileOptions.SequentialScan))
{
 ...
 fs.Write();
}

FILESTREAM 내부에 할당 된 모든 버퍼가 GC에 의해 제 시간에 출시되지 않는다고 생각합니다. 내가 이해하지 못하는 것은 왜 CLR이 던지는 대신 GC 사이클을 실행하고 사용하지 않은 버퍼를 모두 자유롭게하지 않는가?

올바른 솔루션이 없습니다

다른 팁

10 개의 스레드가 코드가 표시된대로 파일을 열면 한 번에 최대 10 개의 분해되지 않은 파일 스트림 객체가 있습니다. 예, Filestream 하다 코드에 "bigbuffersizeinbytes"로 지정하는 내부 버퍼가 있어야합니다. 정확한 가치를 공개 해 주시겠습니까? 이것이 충분히 커지면 (예 : ~ 100MB) 문제의 원인이 될 수 있습니다.

기본적으로 (즉, 시공시 숫자를 지정하지 않을 때),이 버퍼는 4KB이며 일반적으로 대부분의 응용 프로그램에 적합합니다. 일반적으로 디스크 쓰기 성능에 관심이 있다면이 제품을 100KB로 증가시킬 수 있지만 더 이상 증가하지는 않습니다.

그러나 특정 애플리케이션의 경우 그렇게하는 경우에는 의미가 없습니다. 버퍼는 FILESTREAM 객체를 처리하기 전에 작성하기 전에 16-30 바이트를 작성하지 않습니다.

질문에 답하기 위해 요청 된 메모리를 할당 할 수없는 경우에만 OutofMemoryException이 발생합니다. ~ 후에 GC가 실행되었습니다. 다시, 버퍼가 정말로 커지면 시스템에 많은 메모리가 남아있을 수 있습니다. 인접한 큰 덩어리. 큰 물체 힙이 절대로 압축되지 않기 때문입니다.

나는 사람들에게 이것에 대해 몇 번 상기 시켰지만 큰 물체 힙 이용 가능한 메모리의 평화가 있거나 응용 프로그램이 OK가 실행되는 것처럼 보이는 경우에 예외를 상당히 예외적으로 던질 수 있습니다.

나는 당신이 여기서 분리하는 것을 거의 정확하게 수행 할 때이 문제에 대해 상당히 자주 발생합니다.

이 질문에 올바르게 답변하려면 더 많은 코드를 게시해야합니다. 그러나 나는 그것이 잠재적 인 할로윈 문제와 관련이있을 수 있다고 생각합니다. (Spooky Dooky) .

당신이 읽고있는 버퍼는 또한 문제가 될 수 있습니다 (다시 큰 물체 힙 관련)도 다시, 당신은 루프에서 무슨 일이 일어나고 있는지에 대한 자세한 내용을 올려야합니다. 방금 실제로 동일 한 마지막 버그를 못 박았습니다 (입력 파일의 읽기에 걸쳐 독립 상태를 유지 해야하는 많은 병렬 해시 업데이트를 수행하고 있습니다) ....

오프! 그냥 스크롤하고 "bigbuffersizeinbytes"를 발견했습니다. 나는 다시 큰 물체 힙에 기대고 있습니다 ...

내가 당신이라면 (그리고 상황이 부족하기 때문에 이것은 매우 어렵다), 나는 당신의 모든 disperate 스레드가 당신의 큰 후원을 통해 개별적으로 읽을 수 있도록 허용하는 대신 작은 파견 "mbuf"를 제공 할 것입니다. 배열 ... (즉, 매우 미묘한 코드 구문으로 무차별 할당을 유발하지 않기가 어렵습니다).

버퍼는 일반적으로 파일 스트림 내부에 할당되지 않습니다. 아마도 문제는 "수천 개의 작은 버퍼를 쓰는 것"라인 일 것입니다. 일반적으로 여러 번, 여러 번 버퍼를 재사용합니다 (즉, 읽기/쓰기를위한 다른 호출에서).

또한 - 이것은 단일 파일입니까? 단일 파일 스트림은 스레드 안전을 보장하지 않습니다. 따라서 동기화를하지 않으면 혼돈을 기대하십시오.

이러한 제한은 기본 OS에서 발생할 수 있으며 .NET 프레임 워크가 이러한 종류의 한계를 극복 할 수있는 힘이 없을 수 있습니다.

코드 샘플에서 추론 할 수없는 것은 이러한 파일 스트림 객체를 동시에 열거 나 순서대로 빨리 열는지 여부입니다. '사용'키워드를 사용하면 fs.write () 호출 후 파일이 닫히도록합니다. 파일을 닫는 데 GC주기가 필요하지 않습니다.

Filestream 클래스는 실제로 파일에 대한 순차적 읽기/쓰기 액세스를위한 것입니다. 큰 파일에서 임의의 위치에 빠르게 글을 쓰야하는 경우 가상 파일 매핑을 사용하는 것을 살펴볼 수 있습니다.

업데이트 : 가상 파일 매핑은 4.0까지 .NET에서 공식적으로 지원되지 않는 것 같습니다. 이 기능에 대한 타사 구현을 살펴볼 수 있습니다.

데이브

나는 비슷한 것을 경험하고 있고 당신이 당신의 문제의 근본을 고정 시켰는지 궁금해?

내 코드는 파일간에 많은 복사를 수행하여 다른 바이트 파일 사이에 상당히 많은 메그를 전달합니다. 프로세스 메모리 사용이 합리적인 범위 내에 유지되는 동안 시스템 메모리 할당이 복사 중에 너무 높아진다는 것을 알았습니다. 내 프로세스에서 사용하는 것보다 훨씬 더 많습니다.

이 문제를 filestream.write () 호출로 추적했습니다.이 줄이 꺼지면 메모리 사용이 예상대로 진행되는 것 같습니다. 내 bigbuffersizeinbytes는 기본값 (4K)이며, 수집 할 수있는 곳은 어디든 볼 수 없습니다 ...

문제를 보면서 발견 한 것은 감사하게받을 것입니다!

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