If you want to consume all the virtual address space, well, then go ahead and consume it, you don’t need my help


Commenter Matthew Chaboud asks if there's an easy way to consume all the virtual address space below 4GB, short of, well, actually allocating it. "It seems like there should be a cleaner way to do this."

If you want to consume all the virtual address space, then call VirtualAlloc until you turn blue. Programs shouldn't care what address they get back from a memory allocation function; they should handle values below 2GB and above 2GB with equal facility.

It's not like there's a ConsumeAllAvailableVirtualAddressSpaceAndExhaustTheHeap function. (Is there a AllocateAllRemainingDiskSpaceAndFillExistingFilesWithZeroes function?) What would be the point of such a function? Once you call it, you have run out of memory!

If Mr. Chaboud is talking about keeping programs away from bottom 4GB of virtual address space on a 64-bit machine, then a much easier way to do this is to set the AllocationPreference configuration setting to specify that memory should be allocated from high addresses first. (But I don't think that's the scenario that prompted the original question, because on 64-bit Windows, the default heap is above the 4GB boundary, so there would be no need to exhaust the heap in order to consume the memory at virtual addresses below 4GB.)

Correction: Pavel Lebedinsky points out that the default heap is below 4GB on 64-bit machines. It used to be above the 4GB boundary on earlier versions of 64-bit Windows, but I guess they changed it.

Comments (9)
  1. bahbar says:

    I’d suspect the question is specific to 64bit programs, in order to make sure their programs deal cleanly with addresses that don’t fit in 32bits (old code base).

    Call the magic "allocateall4GB", and then, all future allocations will have more bits than fit in DWORD. Anything that does not handle it properly will hopefully crash.

  2. ulric says:

    "AllocationPreference" is "much easier"l well it seems to work on server operating systems, I’d rather use something I know will work.

    We used virtual alloc, or one big malloc, like the questionner did.  (This was years ago now)

    this is done to run automated test to catch at run time any problem where the pointers could be truncated. In large programs, we can’t catch them all with compiler warning.  

    Even with smaller programs, we can have people use the wrong macro or data member in a VARIANT-like union to get a pointer.

  3. Anonymous says:

    Actually, the 16-bit Windows API included a stress-testing function called AllocDiskSpace; as I recall, this created a STRESS.EAT file that filled the disk.

    [That function was not part of the 16-bit Windows API; it was in a stress test helper library that came with the SDK. -Raymond]
  4. DriverDude says:

    Is there a AllocateAllRemainingDiskSpaceAndFillExistingFilesWithZeroes function?

    Hey, I want one of these, but maybe without the FillExistingFilesWithZeros part.

    Filling up a multi-TB disk is so tedious these days and SetFileValidData() requires special privileges. I want an API that anybody can call, that will fill up the whole disk (up to their quota), and creates files that only SYSTEM can access.

    Removing the leftover SYSTEM-only files that will inevitably result from abusing this API is somebody else’s problem. :-)

  5. Pavel Lebedinsky says:

    The default process heap on 64 bit is below 4 GB unless AllocationPreference is changed to force top-down allocations.

  6. Sandman says:

    > Is there a AllocateAllRemainingDiskSpaceAndFillExistingFilesWithZeroes function?

    Hey, I want one of these, but maybe without the FillExistingFilesWithZeros part.

    So what are you filling the diskspace with? If you’ll leaving it as is- you effectively got a security hole.

    As you immediately have read access to all the contents of deleted files. Why do you think SetValidData() requires privs?

    If you’re going to overwrite a large chunk of a disk – it’s going to be slow – I can’t see what you can do about it. (Except to be clever with threads).

  7. porter says:

    > Filling up a multi-TB disk is so tedious these days

    Then use smaller disks?

  8. Maurits says:

    >Hey, I want one of these, but maybe without the FillExistingFilesWithZeros part.

    So what are you filling the diskspace with?

    Pi.

  9. That must be a really old question, as I haven’t had to deal with x64 porting issues for close to a year.

    As some have guessed, the point was to debug code that, scarily enough, had some sections that had gone from win16 to win32 to winx64.  Pavel lended an advisory hand to me back in those days while I wrestled with a number of memory and performance issues.

    I ended up setting the top-down pref and still wrote a FillUp4GB() (or something like that) function.  Compiler warnings about truncation were also immensely helpful.  

    Even before the days of x64 (when we still had builds for nt 5 on the alpha), my team at the time used general memory allocation replacements that could be toggled to fail from the help menu (internal builds) and address-space filling tricks.  Screwing with otherwise repeated initial conditions may not be the best way to test, but I find it an invaluable one.  Thanks for mocking my question (and using my name) on your blog.  I am now immortal in the eyes of my peers.

Comments are closed.