Maybe on proper UNIX (and BSDs) where you have the whole base system as more or less one package, but on Linux certainly not. Honestly the whole concept of "OS" does not make that much sense on traditional Linux distros. You could consider a whole distro an OS, but then the phrase is so all-encompassing that it becomes meaningless. On the other hand calling just the kernel "OS" is not quite right either.
> b) malloc has to get the memory from the OS eventually, via sbrk or mmap.
Yes, eventually and occasionally. But there is fairly big disconnect between malloc and OS. You got me curious, so I did run the code from the article with few different NUM_ALLOCS values to see how it behaves. These are the results from glibc malloc on my system:
Benchmark: Allocate/free 10000000 memory chunks (4-128 bytes)...
70.310378 ns / alloc
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
100.00 0.023622 4 5996 brk
Benchmark: Allocate/free 1000000 memory chunks (4-128 bytes)...
171.745062 ns / alloc
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
100.00 0.250319 17 15004 brk
Benchmark: Allocate/free 100000 memory chunks (4-128 bytes)...
33.700466 ns / alloc
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
100.00 0.000203 3 63 brk
Benchmark: Allocate/free 10000 memory chunks (4-128 bytes)...
30.589104 ns / alloc
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
0.00 0.000000 0 9 brk
Benchmark: Allocate/free 1000 memory chunks (4-128 bytes)...
26.941299 ns / alloc
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
100.00 0.000008 2 4 brk
Note how the syscall count blows up at NUM_ALLOCS=1000000, which just happens to be the original value from the article. Yes, I checked and glibc did not fall back to mmap in any of these cases. You can already start seeing why this might not be the best of benchmarks.Then just for fun, I tried using jemalloc, which is a drop-in replacement for standard malloc. These are the results:
Benchmark: Allocate/free 10000000 memory chunks (4-128 bytes)...
68.486404 ns / alloc
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
100.00 0.000186 4 47 mmap
0.00 0.000000 0 2 brk
Benchmark: Allocate/free 1000000 memory chunks (4-128 bytes)...
59.097052 ns / alloc
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
96.45 0.000544 16 33 mmap
3.55 0.000020 10 2 brk
Benchmark: Allocate/free 100000 memory chunks (4-128 bytes)...
54.659843 ns / alloc
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
0.00 0.000000 0 24 mmap
0.00 0.000000 0 2 brk
Well, well, well. It certainly paints a very different picture.