문제

배경 : 많은 양의 GeoData와 함께 작업하는 C ++ 프로그램을 작성하고 있으며, 한 번에 처리하기 위해 큰 덩어리를로드하고 싶습니다. 32 비트 머신 용으로 컴파일 된 앱으로 작업하는 것이 제한되어 있습니다. 테스트중인 기계는 64 비트 OS (Windows 7)를 실행하고 있으며 6 기가의 RAM이 있습니다. MS VS 2008 사용.

다음 코드가 있습니다.

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;
}

앱이 32 비트 주소 지정의 4 기가 바이트 한계에 도달 할 때까지 메모리를 할당 할 수 있기를 바랐습니다. 그러나 Nbandbytes가 466,560,000 인 경우 새 새로운 시도에서 새로 새로워집니다. 이 단계에서 프로세스의 작업 세트 (메모리) 값은 665,232 K이므로 메모리 공연을 할당 할 수없는 것 같습니다.

32 비트 윈도우의 응용 프로그램에 대한 2 기가 제한에 대한 언급이 있었으며, Win32의 /3GB 스위치를 사용하여 3 gig로 확장 될 수 있습니다. 이것은 해당 환경에서 좋은 조언이지만이 경우와 관련이 없습니다.

32 비트 응용 프로그램으로 64 비트 OS에서 얼마나 많은 메모리를 할당 할 수 있어야합니까?

도움이 되었습니까?

해결책

OS가 당신에게주고 싶어하는만큼. 기본적으로 Windows에는 32 비트 프로세스에 2GB의 주소 공간이 있습니다. 그리고 이것은 여러 덩어리로 나뉩니다. 한 영역은 스택을 위해 제쳐두고, 다른 실행 파일 및로드 된 DLL에 대해 다른 영역이 따로 설정되어 있습니다. 남은 것은 동적으로 할당 될 수 있지만, 큰 인접한 덩어리가 될 것이라는 보장은 없습니다. 각각 수백 MB의 몇 가지 작은 덩어리 일 수 있습니다.

Largeaddressaware 플래그를 컴파일하면 64 비트 Windows가 전체 4GB 주소 공간을 사용할 수 있습니다.

  • 사용 가능한 메모리가 인접하다고 가정해서는 안됩니다. 몇 개의 큰 배분이 아닌 여러 개의 작은 할당으로 작업 할 수 있어야하며
  • 많은 메모리가 필요한 경우 64 비트 응용 프로그램으로 컴파일해야합니다.

다른 팁

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

그러나 귀하의 경우에는 인접한 메모리를 할당하고 있다고 생각합니다. 따라서 예외가 발생했습니다.

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

읽다 이 기사 물리적 메모리, 가상 메모리 및 주소 공간에 대해 생각하는 방법에 대한 좋은 개요 (세 가지 모두 다른 것). 간단히 말해서, 당신은 당신이 RAM만큼 물리적 메모리를 가지고 있지만, 앱은 실제로 물리적 메모리와 전혀 상호 작용할 수 없습니다. 그것은 가상 메모리에 데이터를 저장하기에 편리한 장소 일뿐입니다. 가상 메모리는 PageFile의 크기에 따라 제한되며 앱이 사용할 수있는 금액은 다른 앱이 사용하는 금액으로 제한됩니다 (실제로 사용하지 않도록 더 많이 할당 할 수는 있지만). 32 비트 세계의 주소 공간은 4GB입니다. 그 중 2GB가 커널에 할당됩니다 (또는 /3BG 스위치를 사용하는 경우 1GB). 남은 2GB 중 일부는 스택에 의해 사용됩니다. 일부는 현재 실행중인 프로그램 (및 모든 DLL 등)에 의해 사용됩니다. 그것은 조각화 될 것이며, 당신은 너무 많은 인접한 공간을 얻을 수있을 것입니다 - 이것은 당신의 할당이 실패하는 곳입니다. 그러나 그 주소 공간은 당신이 할당 한 가상 메모리에 액세스하는 편리한 방법이기 때문에 훨씬 더 많은 메모리를 할당하고 한 번에 몇 가지 주소 공간에 덩어리를 가져올 수 있습니다.

Raymond Chen이 그 예를 가지고 있습니다 4GB의 메모리를 할당하고 그 부분을 주소 공간의 한 부분에 매핑하는 방법에 대한 것입니다.

32 비트 창에서 최대 할당 가능은 64 비트 창에서 16TB 및 256TB입니다.

그리고 당신이 실제로 Windows에서 메모리 관리가 작동하는지에 대해 읽으십시오. 이 기사.

Elephantsdream 프로젝트에서 Blender 3D의 Blender Foundation은 비슷한 문제가있었습니다 (Mac에서는). 링크를 포함 할 수 없지만 Google : Blender3D 메모리 할당 문제가 첫 번째 항목이됩니다.

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

Nbandbytes는 466,560,000으로 1.4GB를 할당하려고합니다. 32 비트 앱은 일반적으로 2GB의 메모리에만 액세스 할 수 있습니다 ( /3GB로 부팅하고 실행 파일은 큰 주소 공간 인식으로 표시됩니다). 당신은 당신의 큰 메모리 덩어리를위한 많은 연속 주소 공간을 찾기가 어려울 수 있습니다.

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

프로세스 당 총 약 2GB를 할당 할 수 있어야합니다. 이 기사 (PDF) 세부 사항을 설명합니다. 그러나 아마도 당신은 아마도 그 큰 블록에 가까운 단일의 인접 블록을 얻을 수 없을 것입니다.

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

이 양의 메모리에서 디스크에 수동으로 글을 쓰는 것이 좋습니다. 메모리를 관리하고 필요할 때 임시 파일에 쓰는 클래스로 배열을 감싸십시오. 프로그램의 특성은 디스크를 너무 많이 누르지 않고 해당 데이터의 일부를 효과적으로 캐시 할 수 있기를 바랍니다.

sysinternals vmmap 가상 주소 공간 조각화를 조사하는 데 유용하며, 이는 아마도 만족스러운 메모리를 할당 할 수있는 금액을 제한 할 수 있습니다. 여유 공간을 표시 한 다음 크기별로 정렬하여 가장 큰 자유 영역을 찾은 다음 주소로 정렬하여 가장 큰 자유 영역 (아마도 DLL, 공유 메모리 영역 또는 기타 힙)을 분리하는 것을 확인하십시오.

매우 큰 인접 할당을 피하는 것은 아마도 다른 사람들이 제안한 것처럼 아마도 최선일 것입니다.

환경 LARGE_ADDRESS_AWARE=YES (JALF가 제안한 것처럼) 응용 프로그램에 의존하는 라이브러리가 호환되는 한 좋습니다. 그렇게하면 코드를 AllocationPreference 하향식 가상 주소 할당을 활성화하기위한 레지스트리 키 세트.

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