views:

236

answers:

4

How to make a block of memory allocated by malloc() or new:

  • immediately swapped out,
  • or lazily initialized.

In fact, I'm trying to reserve an address space. How to accomplish this?

PS. How to verify, from the user space, if a memory block is swapped out?

+2  A: 

To reserve a chunk of address space:

On unix, sbrk() or mmap().

On Windows, VirtualAlloc().

Ben Voigt
+2  A: 

On Windows, you can do this with the VirtualAlloc function.

I don't know of any way to do it on Linux or OS X.

greyfade
+3  A: 

malloc is often implemented using mmap, so if you were to use malloc, you'd get the behavior you're after anyway. After all, why sould allocating memory force other pages out of cache when there's no guarantee that the new pages will be initialized immediately? I know that Open BSD implements malloc this way, and GNU's C lib uses mmap if your allocation is larger than some limit. I think it's just a couple pages.

I don't know about how Windows goes about all of this, but check the VirtualAlloc docs to see if it is specific about its purpose. If it documents that Windows' malloc caches its pages, then you have your answer and you should use VirtualAlloc.

VirtualAlloc automatically zeros memory. I'd expect that to mean it has to load it to write to it. I tried VirtualAlloc(NULL, 1024*1024, [combinations of commit and reserve], [large pages on or off]) and never received memory that I could assign to. I've seen docs that explicitly state that VirtualAlloc should not be used for general use memory.... When I do a malloc in Visual Studio, the process' physical memory and virtual memory use both shoot up. The phys memory doesn't go up by the full gig I asked for, but it is very close. You may need to find a different option in windows.
A: 

On Linux, BSD, or OS X, use malloc. I think the popular "jemalloc" implementation on FreeBSD uses a dedicated mmap for every region 1 MiB or larger. The smaller regions are still backed by mmap, so they still give most of the same behavior, but when you free the smaller regions you won't automatically unmap them. I think. The glibc "dlmalloc" implementation, which is used on Linux, also uses a dedicated mmap for allocations at least 1 MiB, but I think it uses sbrk for smaller regions. Mac OS X's malloc also uses mmap but I am not sure about the particular parameters.

A pointer that you get from a large malloc will point to a shared page in RAM filled with zero bytes. As soon as you write to a page in that region, a new page in physical RAM will be allocated and filled with zero bytes. So you see, the default behavior of malloc is already lazy. It's not that the pages are swapped out to start with, it's that they aren't even there to begin with.

If you are done with the data in a region, you can use madvise with MADV_FREE. This tells the kernel that it can free the related pages instead of swapping them out. The pages remain valid, and as soon as you write to them they'll turn back into normal pages. This is kind of like calling free and then malloc.

Summary: Just use malloc. It does what you want.

Dietrich Epp