title: MapViewOfFile() no longer works after process hits the 2GB limit
body: <p>MapViewOfFile() works without any problem if our process has not hit the 2GB limit yet. However if the process hits the limit then MapViewOfFile() no longer works even if some or all of the memory is deallocated. GetLastError() returns 8, which means <code>ERROR_NOT_ENOUGH_MEMORY, Not enough storage is available to process this command</code>. Here is a small program showing the problem:</p>
  
  <pre><code>#include &lt;Windows.h&gt;
  #include &lt;cstdio&gt;
  #include &lt;vector&gt;
  
  const int sizeOfTheFileMappingObject = 20;
  const int numberOfBytesToMap = sizeOfTheFileMappingObject;
  const char* fileMappingObjectName = "Global\\QWERTY";
  
  void Allocate2GBMemoryWithMalloc(std::vector&lt;void*&gt;* addresses)
  {
      const size_t sizeOfMemAllocatedAtOnce = 32 * 1024;
      for (;;) {
          void* address = malloc(sizeOfMemAllocatedAtOnce);
          if (address != NULL) {
              addresses-&gt;push_back(address);
          }
          else {
              printf("The %dth malloc() returned NULL. Allocated memory: %d MB\n",
                  addresses-&gt;size() + 1,
                  (addresses-&gt;size() * sizeOfMemAllocatedAtOnce) / (1024 * 1024));
              break;
          }
      }
  }
  
  void DeallocateMemoryWithFree(std::vector&lt;void*&gt;* addresses)
  {
      std::vector&lt;void*&gt;::iterator current = addresses-&gt;begin();
      std::vector&lt;void*&gt;::iterator end = addresses-&gt;end();
      for (; current != end; ++current) {
          free(*current);
      }
      addresses-&gt;clear();
      printf("Memory is deallocated.\n");
  }
  
  void TryToMapViewOfFile()
  {
      HANDLE fileMapping = OpenFileMappingA(FILE_MAP_ALL_ACCESS, FALSE,
          fileMappingObjectName);
      if (fileMapping == NULL) {
          printf("OpenFileMapping() failed. LastError: %d\n", GetLastError());
          return;
      }
  
      LPVOID mappedView = MapViewOfFile(fileMapping, FILE_MAP_READ, 0, 0,
          numberOfBytesToMap);
      if (mappedView == NULL) {
          printf("MapViewOfFile() failed. LastError: %d\n", GetLastError());
          if (!CloseHandle(fileMapping)) {
              printf("CloseHandle() failed. LastError: %d\n", GetLastError());
          }
          return;
      }
  
      if (!UnmapViewOfFile(mappedView)) {
          printf("UnmapViewOfFile() failed. LastError: %d\n", GetLastError());
          if (!CloseHandle(fileMapping)) {
              printf("CloseHandle() failed. LastError: %d\n", GetLastError());
          }
          return;
      }
  
      if (!CloseHandle(fileMapping)) {
          printf("CloseHandle() failed. LastError: %d\n", GetLastError());
          return;
      }
  
      printf("MapViewOfFile() succeeded.\n");
  }
  
  int main(int argc, char* argv[])
  {
      HANDLE fileMapping = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL,
          PAGE_READWRITE, 0, sizeOfTheFileMappingObject, fileMappingObjectName);
      if (fileMapping == NULL) {
          printf("CreateFileMapping() failed. LastError: %d\n", GetLastError());
          return -1;
      }
  
      TryToMapViewOfFile();
  
      std::vector&lt;void*&gt; addresses;
  
      Allocate2GBMemoryWithMalloc(&amp;addresses);
  
      TryToMapViewOfFile();
  
      DeallocateMemoryWithFree(&amp;addresses);
  
      TryToMapViewOfFile();
  
      Allocate2GBMemoryWithMalloc(&amp;addresses);
  
      DeallocateMemoryWithFree(&amp;addresses);
  
      if (!CloseHandle(fileMapping)) {
          printf("CloseHandle() failed. LastError: %d\n", GetLastError());
      }
  
      return 0;
  }
  </code></pre>
  
  <p>The output of the program:</p>
  
  <pre><code>MapViewOfFile() succeeded.
  The 65126th malloc() returned NULL. Allocated memory: 2035 MB
  MapViewOfFile() failed. LastError: 8
  Memory is deallocated.
  MapViewOfFile() failed. LastError: 8
  The 64783th malloc() returned NULL. Allocated memory: 2024 MB
  Memory is deallocated.
  </code></pre>
  
  <p>As you can see MapViewOfFile() fails with 8 even after releasing all memory that was allocated. Even though MapViewOfFile() reports <code>ERROR_NOT_ENOUGH_MEMORY</code> we can call malloc() successfully.</p>
  
  <p>We ran this example program on Windows7,32bit; Windows 8.1,32bit and Windows Server 2008 R2,64bit and the results were the same.</p>
  
  <p>So the question is: Why does MapViewOfFile() fail with <code>ERROR_NOT_ENOUGH_MEMORY</code> after the process hits the 2GB limit?</p>