Resizeable memory maps
Opened this issue · 3 comments
GC_map()
currently tells the kernel to allocate as much (virtual) memory as possible, but we could be smarter about it. Instead of asking for as much memory as there are on the computer (thrice), we could tell to map as much as we need, and grow the map as we grow the GC HEAP using mremap(2)
.
Ideally, we could consider to shrink it after a collect (or once every collect) if we could release a significant amount of memory back to the OS.
Note: allocating so much memory causes issues with Valgrind that intercepts the mmap
call and injects the MAP_FIXED
flag which tells the kernel to fully allocate memory, which isn't possible and crashes the program (oops).
I hit some issues while trying to implement this:
munmap
can shrink a previously allocated mmap
, but this is definitive: the memory is no longer accessible (trying to access it will segfault). Despite being capable to pass an address, we can't mmap
the released memory again to "grow" the map again. The address is a mere hint and the memory is allocated anywhere (at least on Linux).
mremap
should be capable to shrink/grow a mmap
, but it's only available in Linux and hidden behind the _GNU_SOURCE
flag. It's not portable to anything else (e.g. Darwin, FreeBSD or OpenBSD).
An alternative could be to use sbrk
to dynamically grow or shrink the DATA section (beware to copy the original end
of the DATA section for the collector to not walk the GC HEAP 😨). It's legacy but should be broadly available.
Except that we need two maps: one for the small objects and another one for the large objects, while sbrk
only gives us access to a single one 🤦
We can actually tell the kernel that it can release pages using madvise
with the MADV_DONTNEED
flag, while still being able to reference that memory later on (which may be the memory as we left it, or be initialized at zero after a page fault).
We can even create "holes" in the memory mapping, as long as we can expect a block header to be initialized at zero this should be fine (at the expense of page faults).