2014-06-18 4 views
0

많은 개체 모음을 비교하고 모든 일치 항목을 저장하기위한 몇 가지 코드로 작업하고 있습니다.대용량 데이터 세트 및 메모리 제한 작업

당연히, 난 그냥 발생 가지고 System.OutofMemoryException

가 어떻게이 문제를 해결하는 갈 수 ?

비교하는 동안 메모리에 쓰고 다른 결과를 disk/rdbms에 써야합니다. 즉 버퍼를 생성한다.

+2

콜렉션을 유지해야합니까? 기억에? 어쩌면 예제 코드를 보여줄 수 있을까요? – Magnus

+0

메모리에 가능한 한 적은 수의 개체를 동시에 저장하십시오. 가능한 한 빨리 사용하지 않는 자원을 모두 비우십시오. 가능한 빨리 디스크/db에 사용하지 않는 데이터를 저장하십시오. 모든 것이 가능한 한 최적화되면 하드웨어에 집중하십시오. 컴퓨터에 충분한 RAM이 있고 응용 프로그램 풀이 충분히 할당되었는지 확인하십시오 (IIS에서 호스팅되는 웹 응용 프로그램 인 경우) – HaukurHaf

답변

5

사실 사용자 환경, 특히 x86 또는 x64 운영 체제에 따라 다릅니다. 여기에서 자세한 내용을 확인하십시오 : Memory in depth

1. 스트리밍이 필요한 곳에서 고급 시나리오가 있습니다. 정확한 솔루션은 데이터를 가져 오는 위치에 따라 다릅니다. SQL 데이터베이스에서 데이터를 당기는 경우에 당신은 단단히이 경우 비동기와 결합하여 SqlDataReader, 샘플 코드를 스트리밍 사용할 수 있습니다

using (SqlDataReader reader = await command.ExecuteReaderAsync(CommandBehavior.SequentialAccess)) 
{ 
    if (await reader.ReadAsync()) 
    { 
     if (!(await reader.IsDBNullAsync(0))) 
     { 
      using (var dataStream = reader.GetStream(0)) 
      { 
       //process the data 
      } 
      } 
     } 
} 

이 링크를 좀 더 자세한 사항 공개됩니다 Retrieving large data set합니다. 그러나 이러한 접근 방식은 비동기 코드를 처리 할뿐만 아니라 연결 문자열에서 비동기를 사용하도록 강요합니다. 특히 비공식 코드를 처리해야하는 경우 (특히 사양/테스트를 포함하려는 경우) 더욱 그렇습니다.

while(true) 
{ 
int count = 0; 
bool canRead = reader.Read(); 
while(canRead) 
{ 
    canRead = reader.Read(); 
    count++; 
    if (count >= batchSize) 
    break; 
} 

if (!canRead) 
    break; 
} 
:

2.Yet 또 다른 접근 방법은 모든로드되지 않는 즉, 데이터의 새로운 배치를 가져 오는 예제 코드를 계속 한 후, 즉 일부 허용 한계까지 데이터를 버퍼링 한 후 코드를 소모하기위한 배치를 노출, 배치입니다

1 행 데이터 크기 (테이블 스키마, msdn article)를 대략적으로 계산하거나 가장 적합한 값으로 구성하고 재생할 수있는 대략적인 배치 크기입니다. 이 접근법의 가장 큰 장점은 코드에 최소한의 변경 만 있으면되고 코드 자체는 동기 상태라는 것입니다. 단점은 매번 활성 연결을 유지하거나 새 연결을 열어두고 이미 읽은 레코드와 가져 오기가 필요한 레코드를 유지해야한다는 것입니다.

마지막으로 두 가지 옵션을 사용하면 데이터의 일부만 가져오고 연결이 끊어지면 (장애 조치 메커니즘이 필요함) 수행 할 수있는 기능과 같은 고급 문제를 처리해야합니다. 특정 시간 초과 후 장기 실행 검색 작업 취소 등

결론적으로 대규모 데이터에서 발생하는 추가 복잡성을 처리하고 싶지 않은 경우이 작업을 시장에서 사용할 수있는 데이터베이스 또는 타사 프레임 워크에 위임하십시오. 팀에 충분한 기술이 있다고 생각되면 직접 구현하고 디스크 파일에서 비교 결과를 유지하거나 메모리 내 캐시를 사용하거나 데이터를 데이터베이스에 푸시하십시오.

+0

굉장한 답변 감사합니다. –

1

먼저 사용중인 프로세서 아키텍처에 따라 다릅니다. 32 비트 아키텍처를 사용하는 경우 프로세스 당 2GB의 메모리 만 사용할 수 있습니다. 이 경우 당신은 당신이 거기에 저장할 수있는 것에 의해 정말로 제한됩니다. 64 비트 프로세서는 훨씬 더 많은 메모리를 허용하지만,이 경우에는 괜찮습니다.

메모리 부족 예외가 메모리가 충분하지 않다는 것을 의미하지 않는다는 것은 프로세스가 필요한 메모리 블록을 연속적으로 할당 할 수 없다는 것을 의미합니다. 크기가 1GB 인 어레이와 같이 매우 큰 객체를 할당하려는 경우 프로세스는 해당 1GB에 대한 연속적인 메모리 블록을 찾아야합니다.

구체적인 답변은 상황에 따라 다르지만 일반적으로 64 비트 아키텍처로 전환 한 다음 할당 된 가장 큰 개체의 크기가 얼마나 큰지 검토합니다. 아무 것도 개선되지 않으면 디스크에 정보를 저장하는 것에 대해 생각해야합니다.

관련 문제