2009-06-23 7 views
7

배경 : 나는 많은 양의 지리 데이터로 작업하는 C++ 프로그램을 작성 중이며 한 번에 처리 할 큰 청크를로드하려고합니다. 32 비트 컴퓨터 용으로 컴파일 된 응용 프로그램을 사용하는 데 제약이 있습니다. 내가 테스트하고있는 컴퓨터는 64 비트 OS (Windows 7)를 실행 중이며 6 기가의 RAM이 있습니다. 사용 MS VS 2008얼마나 많은 메모리를 할당 할 수 있습니까?

나는 다음과 같은 코드를 가지고 : 나는 응용 프로그램이 32 비트 주소의 4 기가 바이트 한계에 도달 할 때까지 내가 메모리를 할당 할 수있을 것이라고 기대했다

byte* pTempBuffer2[3]; 
try 
{ 
    //size_t nBufSize = nBandBytes*m_nBandCount; 
    pTempBuffer2[0] = new byte[nBandBytes]; 
    pTempBuffer2[1] = new byte[nBandBytes]; 
    pTempBuffer2[2] = new byte[nBandBytes]; 
} 
catch (std::bad_alloc) 
{ 
    // If we didn't get the memory just don't buffer and we will get data one 
    // piece at a time. 
    return; 
} 

합니다. 그러나 nBandBytes가 466,560,000이면 두 번째 시도에서 std :: bad_alloc을 throw합니다. 이 단계에서 프로세스의 작업 집합 (메모리) 값은 665,232 K입니다. 따라서 할당 된 메모리조차도 얻을 수없는 것 같습니다.

win32 용/3GB 스위치를 사용하여 3 기가로 확장 할 수있는 32 비트 Windows의 응용 프로그램에 대한 2 기가 제한에 대한 언급이있었습니다. 이는 해당 환경에서 좋은 조언이지만이 경우에는 관련이 없습니다.

64 비트 OS에서 32 비트 응용 프로그램으로 할당 할 수있는 메모리 용량은 어느 정도입니까?

+0

웹에서이 참조를 발견했습니다. "64 비트 OS에서 32 비트 응용 프로그램으로 실행하는 경우 4G 주소 공간을 모두 확보 할 수 있으며 모든 물리적 메모리가 물리적 메모리로 백업 될 수 있습니다. 심지어 당신이 64 비트 포인터를 사용하지 않고도 RAM을가집니다.) 블로그 : http://blogs.msdn.com/ricom/archive/2009/06/10/visual-studio-why-is-there-no-64-bit-version.aspx – Bill

+0

내 32 비트 컴퓨터에서 466,560,000 × 3 바이트를 간단한 테스트로 할당 할 수 있습니다. 당신의 경우 할당 포인트에서 이미 조각난 프로세스 메모리로 보입니다. –

+1

이 질문에 대한 답을 고르는 데 어려움을 겪었습니다. 대답은 복잡하고 많은 요인에 따라 다릅니다. 메모리 매핑 된 파일은 좋은 대답이지만이 문제의 근본 원인은 메모리 조각화 인 것 같습니다. bke1은 메모리를보기위한 좋은 도구를 지적했으며 많은 사람들이 메모리 조각화에 대해 이야기했지만 문제를 명확히 언급하고 (64 비트 및 4 비트에서 4 기가비트) 하드 디스크를 제공하는 첫 번째 대답을 선택했습니다. – Bill

답변

10

OS가 원하는만큼. 기본적으로 Windows는 32 비트 프로세스에 2GB의 주소 공간을 허용합니다. 그리고 이것은 여러 덩어리로 나뉘어져 있습니다. 하나의 영역은 스택을 위해, 다른 하나는 실행 파일과로드 된 dll 각각에 대해 설정됩니다. 남아있는 것은 무엇이든 동적으로 할당 될 수 있지만, 하나의 큰 연속적인 덩어리가 될 것이라는 보장은 없습니다. 각각 몇 백 메가 바이트의 작은 덩어리가 될 수 있습니다. 당신이 LARGEADDRESSAWARE 플래그로 컴파일 할 경우

, 64 비트 Windows는 조금 도움이 될 것입니다 전체 4 기가 바이트 주소 공간을 사용하게됩니다 만, 일반적으로

  • 당신은 사용할 수 있다고 가정해서는 안 메모리가 인접 해 있습니다. 몇 개의 큰 할당보다는 여러 개의 작은 할당으로 작업 할 수 있어야하고
  • 많은 메모리가 필요할 경우 64 비트 응용 프로그램으로 컴파일해야합니다.
+0

"사용 가능한 메모리가 연속적이라고 가정하면 안됩니다. 몇 개의 큰 할당보다는 여러 개의 작은 할당으로 작업 할 수 있어야합니다."Windows에서 페이징 된 메모리를 사용하고 응용 프로그램에 대해 연속적이므로 잘못되었습니다. 큰 덩어리 – Lodle

+1

Lodle, 당신은 혼란스러운 주소 공간과 무료 주소 공간입니다. 예 : 가장 일반적인 조각화 중 하나는 코드 자체에 의해 발생합니다. EXE와 DLL은 0x00000000부터 시작하지 않습니다. – MSalters

+0

@Lodle : 아니요, 응용 프로그램은 인접한 주소 공간을 보지만 exe, dll, 스택 및 정적 변수는 모두 해당 주소 공간 내의 다른 주소에로드됩니다. – jalf

6

windows 32 비트에서 일반 프로세스는 최대 2GB를 취할 수 있지만 /3GB 스위치를 사용하면 3GB (Windows 2003의 경우)까지 도달 할 수 있습니다.

하지만 귀하의 경우에는 연속 메모리를 할당한다고 생각하므로 예외가 발생했습니다.

+3

+1 - 인접한 배열을 할당하는 것이 당신에게 가장 많은 "인접한"메모리를 줄 수 있다는 사실을 결코 고려하지 않았습니다! 정말 좋은 지적이야. –

+1

/3GB 스위치는 약간 위험합니다. 많은 드라이버는 스위치로 테스트되지 않으므로 OS가 1GB로 제한되어있을 때 불안정해질 수 있습니다. 그는 64 비트 Windows에서 실행되기 때문에 문제가되지 않습니다. – jalf

+1

당신이 말하는 내용을 이해하는 데 도움이되도록 노력하겠습니다. 작은 덩어리로 메모리를 할당하면 더 많은 총 메모리를 할당받을 수 있다고 말하고 있습니까? – Bill

1

nBandBytes가 466,560,000 인 경우 1.4GB를 할당하려고합니다. 32 비트 응용 프로그램은 일반적으로 2GB의 메모리에만 액세스 할 수 있습니다 (/ 3GB로 부팅하고 실행 파일이 큰 주소 공간 인식으로 표시된 경우 더 많음). 큰 메모리 덩어리에 대해 연속 된 주소 공간 블록을 찾기 란 어렵습니다.

64 비트 OS에서 기가 바이트의 메모리를 할당하려면 64 비트 프로세스를 사용하십시오.

+0

1.4GB는 어떻게 구합니까? 바이트를 4 바이트라고 가정합니까? : p – jalf

+0

3 * 466,560,000. 그는 3 개의 배열을 할당하고 있습니다. – Michael

+0

맞습니다. 저는 1.3 기가 바이트의 메모리를 할당 할 수 있기를 바랬습니다. 할 수 없을 때 놀랐습니다. – Bill

1

프로세스 당 약 2GB를 할당 할 수 있어야합니다. This article (PDF)에서 자세한 내용을 설명합니다. 그러나, 당신은 아마도 그것보다 큰 단일 연속 블록을 얻을 수 없을 것입니다.

1

작은 단위로 할당하더라도 주변 프로그램에 예측할 수없는 메모리 동작이 있거나 다른 운영 체제에서 실행해야하는 경우 특히 필요한 메모리를 확보 할 수 없습니다. 내 경험에 의하면, 32 비트 프로세스의 힙 공간은 약 1.2GB입니다.

이 메모리 양은 수동으로 디스크에 기록하는 것이 좋습니다. 필요한 경우 메모리를 관리하고 임시 파일에 쓰는 클래스에 배열을 래핑하십시오. 프로그램의 특성상 디스크를 너무 많이 사용하지 않고도 데이터의 일부를 효율적으로 캐시 할 수 있기를 바랍니다.

4

페이지 파일만큼 메모리를 할당 할 수 있습니다./3GB 스위치가 없어도 4GB의 메모리를 별 어려움없이 할당 할 수 있습니다.

실제 메모리, 가상 메모리 및 주소 공간 (세 가지 모두 다른 경우)에 대해 생각하는 방법에 대한 좋은 개요는 this article을 참조하십시오. 간단히 말해서, RAM을 보유하고있는 것과 똑같은만큼의 실제 메모리를 보유하고 있지만 실제 메모리와는 아무런 상호 작용이 없습니다. 가상 메모리에 데이터를 저장하는 편리한 장소입니다. 가상 메모리는 페이지 파일의 크기에 따라 제한되며, 응용 프로그램에서 사용할 수있는 양은 다른 응용 프로그램의 사용량에 따라 제한됩니다 (더 많이 할당 할 수 있지만 실제로 사용하지 않는 경우). 32 비트 세계에서 주소 공간은 4GB입니다. 그 중 2GB는 커널에 할당됩니다 (또는/3BG 스위치를 사용하는 경우 1GB). 남아있는 2GB 중 일부는 스택에 의해, 일부는 현재 실행중인 프로그램에 의해 (그리고 모든 dll 등) 사용되지 않을 것입니다. 단편화 될 것입니다. 그리고 여러분은 단지 너무 많은 인접 공간을 얻을 수 있습니다. 이것은 할당이 실패한 곳입니다. 그러나 그 주소 공간은 당신이 할당 한 가상 메모리에 접근하기위한 편리한 방법 일 뿐이므로 훨씬 많은 메모리를 할당 할 수 있으며 한 번에 몇 개의 주소 공간에 그 덩어리를 가져올 수 있습니다.

Raymond Chen has an example 4GB의 메모리를 할당하고 주소 공간의 일부분에 그 부분을 매핑하는 방법.

32 비트 Windows에서는 64 비트 Windows에서 최대 할당 가능 용량이 16TB 및 256TB입니다.

Windows에서 메모리 관리가 실제로 작동하는 방법을 알고 있다면 this article을 읽어보십시오.

2

ElephantsDream 프로젝트 동안 블렌더 파운데이션과 블렌더 파운데이션은 비슷한 문제를 가지고 있습니다 (Mac에서도). 링크를 포함 할 수 없지만 google : blender3d 메모리 할당 문제가 있으며 첫 번째 항목이됩니다.

이 솔루션은 파일 매핑과 관련이 있습니다. 직접 시도하지는 않았지만 여기에서 읽을 수 있습니다. http://msdn.microsoft.com/en-us/library/aa366556(VS.85).aspx

1

Sysinternals VMMap은 할당 할 수있는 연속 메모리의 양을 제한하는 가상 주소 공간 조각화를 조사하는 데 적합합니다. 여유 공간을 표시하도록 설정 한 다음 크기별로 정렬하여 가장 큰 빈 영역을 찾은 다음 주소별로 정렬하여 가장 큰 빈 영역 (리베이스 된 DLL, 공유 메모리 영역 또는 다른 힙)을 구분하는 것이 무엇인지 확인하십시오.

극도로 큰 연속 할당을 피하는 것이 좋습니다. 다른 제안이 있습니다.

귀하의 응용 프로그램이 의존하는 라이브러리가 호환되는 한 LARGE_ADDRESS_AWARE=YES을 설정하는 것이 좋습니다. 이렇게하려면 AllocationPreference 레지스트리 키를 사용하여 코드를 테스트하여 하향식 가상 주소 할당을 사용하도록 설정해야합니다.

+0

좋은 생각 - VMMap을 사용해 보겠습니다. – Bill

관련 문제