3

I try using mmap function to allocate a large amount of memory in virtual space. My need is about of 30Gb, but it can't. I tried with 20Gb with the same result. I executed my test on OVH 64 bits machine server with 60Gb RAM.

My test code:

#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
#include <errno.h>

int main()
{
   void *r = NULL;

   printf("%lu\n", sizeof(size_t));

   r = mmap(NULL, ((size_t)20)*1024*1024*1024, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);

   printf("%d %s\n", r == MAP_FAILED, strerror(errno));

   return 0;
}

The result of execution:

8
1 Cannot allocate memory

Someone can tell me if it's possible or not to allocate 30Gb of virtual memory with mmap, and why ? Elsewhat how to allocate 30Gb with another way ?

Please, don't ask why i want to do that or it's stupid or another philosophic thoughts. It's my need and i just want to find a way to do it if it's possible.

Corebreaker
  • 357
  • 1
  • 11
  • 3
    Ok, why do you want to do that? I know you asked us not to ask you that, but knowing what you're trying to accomplish could help us to help you. I suspect you may have an [XY problem](http://meta.stackexchange.com/q/66377/167210). – Keith Thompson Dec 25 '14 at 21:02
  • @πάνταῥεῖ it doesn't solve the problem. since `size_t` should be good enough to represent any size appears in the memory, i.e. in 64bit system, it has to be at least 64 bit. – Jason Hu Dec 25 '14 at 21:02
  • 1
    How would you describe printing out strerror(errno) and asking for help, without telling us the error? – Martin James Dec 25 '14 at 21:03
  • i think you need to introduce data base to you system. the solution you are working on is not scalable at all. and ordinary people won't have a chance to reproduce it. personally i think it's a good question though. i don't know why people downvote it. – Jason Hu Dec 25 '14 at 21:03
  • On 64 bits systems => 2**64 ! – Corebreaker Dec 25 '14 at 21:03
  • Are you sure you compiled your program as a 64 bit application? Even if you have a 64 bit CPU, you can still run 32 bit software on it. Check the output of `printf("%zd\n", sizeof(size_t));`. – cmaster - reinstate monica Dec 25 '14 at 21:04
  • 1
    You're missing `#include `, required for `strerror()`. – Keith Thompson Dec 25 '14 at 21:05
  • 5
    What is errno? Is it a secret? – Martin James Dec 25 '14 at 21:05
  • Also, are there any disk quotas set? – Martin James Dec 25 '14 at 21:06
  • @KeithThompson - that would surely fail to compile/link? – Martin James Dec 25 '14 at 21:08
  • @MartinJames: Not necessarily. C90 permits calls to functions with no visible declaration; they're assumed to return `int`. C99 dropped the "implicit `int`" rule, but many compilers still permit it. gcc, by default, doesn't complain about the call, but does complain about the `printf` call because it thinks `strerror` returns an `int`. – Keith Thompson Dec 25 '14 at 21:12
  • @KeithThompson Orite:) – Martin James Dec 25 '14 at 21:13
  • 2
    Can you allocate less? Where's the point at which it starts to fail? – The Archetypal Paul Dec 25 '14 at 21:14
  • See this question for some more settings you might want to check. Please show us the output in any case. http://stackoverflow.com/questions/12667397/mmap-returns-can-not-allocate-memory-even-though-there-is-enough?rq=1 – The Archetypal Paul Dec 25 '14 at 21:15
  • 1
    Please update your question to show `sizeof (size_t)` on your system (or the value of `SIZE_MAX`). And try a loop that starts trying to `mmap` and then `munmap`, say, 1 gigabyte, and increases the allocation size by 1 gigabyte until it fails. You could even do a binary search to determine *exactly* when it fails. – Keith Thompson Dec 25 '14 at 21:16
  • 2
    @Paul - that would require debugging acumen: actually investigating the problem by changing stuff. That seems to be off-topic for SO posters these days:( – Martin James Dec 25 '14 at 21:16
  • - errno is "Cannot allocate memory" (ENOMEM), the free memory was enough - No disk quota set - I compiled on 64 bits systems (ubuntu64 14.04) with gcc so sizeof(size_t) == 8 – Corebreaker Dec 25 '14 at 21:18
  • Reloated: http://stackoverflow.com/questions/2159456/whats-the-max-file-mapping-size-in-64bits-machine – M.M Dec 25 '14 at 21:25
  • @KeithThompson he could be building 7-piece tablebases for chess – M.M Dec 25 '14 at 21:26
  • Tested your code on ubuntu 12.04 - it seems to work ok ("0 Success"). – kestasx Dec 25 '14 at 21:27
  • 5
    If you are on Linux check the maximum memory limit for your user with `ulimit -a` – vz0 Dec 25 '14 at 21:27
  • do you need the memory or the address space? if the former, use MAP_NORESERVE, and think very carefully about passing null so that the file is backed with swap. You likely want a backing file on a filesystem that supports sparse files. mmap is the best way of doing this – camelccc Dec 26 '14 at 00:48

1 Answers1

4

I ran your program on Linux Mint 17 (roughly Ubuntu 14.04) x86_64 without error. My system has 8G of RAM, 16G of swap, most of the 8G currently used by page cache, and 1-2GB currently used by processes.

(Incidentally, for questions like this, you really need to specify your platform in detail.)

I was able to reproduce your error message in two different ways.

First way:

$ ./mmap
8
0 Success
$ ulimit -v 65536
$ ./mmap
8
1 Cannot allocate memory

Second way (from a new shell):

$ ./mmap
8
0 Success
$ sysctl vm.overcommit_memory
vm.overcommit_memory = 0
$ sudo sysctl vm.overcommit_memory=2
vm.overcommit_memory = 2
$ ./mmap
8
1 Cannot allocate memory

So, as @vz0 asked, what does ulimit -a say?

How much swap do you have, how much memory is in use, and how does your system have vm.overcommit_memory set?

I am going to go out on a limb a bit and assert that one of these is your culprit.

Nemo
  • 70,042
  • 10
  • 116
  • 153