Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does calling mmap() with large size not fail?

I try to use mmap() to manipulate virtual memory. I want to reserve and commit a region of memory. I tested this code:

const unsigned long gygabyte = 1024 * 1024 * 1024;
const unsigned long gygabyteCount = 2;
const unsigned long maxCapacity = gygabyteCount * gygabyte;

int main()
{
    char* pMemory;

    pMemory = (char*)mmap(NULL, maxCapacity, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
    if ( mprotect(pMemory, maxCapacity, PROT_READ | PROT_WRITE) != 0 )
    {
        cout << "Memory Allocation has failed" << endl;
    }
    usleep(-1);

    return 0;
}

I ran several copies of my program (say 6) from a terminal. I didn't ever see "Memory Allocation has failed" in any one. I'm running on 64-bit Ubuntu with 4GB RAM. Can anyone tell me something about this?

like image 632
antpetr89 Avatar asked Feb 03 '12 12:02

antpetr89


People also ask

Why is mmap faster than malloc?

Almost always, memory is much faster than disk, and malloc is not what's costing time. The mmap code is faster because for your program, mmap has resulted in either less disk access, or more efficient disk access, than whatever reads and writes you compared against.

What does mmap return on failure?

Upon successful completion, the mmap() function returns the address at which the mapping was placed; otherwise, it returns a value of MAP_FAILED, which has a value of 0, and sets errno to indicate the error.

Does mmap cause page fault?

It doesn't actually put anything into physical memory at all. After you call mmap , the allocated region probably doesn't even point to physical memory: accessing it will cause a page fault. This kind of page fault is transparently handled by the kernel, in fact, this is one of the kernel's primary duties.

Why is mmap slow?

Even though it is important and often used, mmap can be slow and inconsistent in its timing. Mmap maps memory pages directly to bytes on disk. With mmap, whenever there is a pagefault, the kernel pulls the page directly from disk into the program's memory space.


1 Answers

mmap reserves a region of the process's virtual address space, but does not immediately allocate physical RAM for it. Therefore, on a 64-bit platform, you can reserve a vast amount without failure (although you still need to check for failure; your example code doesn't). Physical pages of RAM are allocated later when the memory is accessed.

mprotect just changes the read/write access of the reserved memory; it won't make it resident in RAM either. You would get the same effect by passing PROT_READ | PROT_WRITE instead of PROT_NONE to mmap, and removing the call to mprotect.

If you need the memory to be resident in RAM straight away, then use mlock for that. It will fail if there isn't enough RAM available. On many linux platforms (including Ubuntu), there is a resource limit (RLIMIT_MEMLOCK) which restricts how much memory any process can lock; you can adjust this with ulimit -l.

like image 152
Mike Seymour Avatar answered Oct 24 '22 07:10

Mike Seymour