mimalloc icon indicating copy to clipboard operation
mimalloc copied to clipboard

How can mimalloc manage a piece of allocated memory?

Open CS0522 opened this issue 1 year ago • 6 comments

I have already allocated a piece of big memory by mmap, the memory size (as MEM_SIZE) is large, so I want to use it as a memory pool, or a heap, so that I can use the memory efficiently. For example, every time I want a piece of memory (large but not larger than MEM_SIZE), I can just easily use a function to allocate and get a void *, and release this pointer later, and the pool/heap can collect this memory. An example:

// allocate memory
void* mem_ptr = mmap(NULL, MEM_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

// create a heap or memory pool based on the allocated memory
// is there a function works as create_heap(...)?
auto my_heap = create_heap(mem_ptr, MEM_SIZE);

// when I need to get some memory
void* mem_for_var1 = alloc(my_heap, mem_size_for_var1);
auto var1 = new (mem_for_var1) float();

// use var1

// release
...

And if there exists any memory allocator or memory pool library for C++ that can work as above, it is appreciated if you could tell me and leave some examples or the documents of it.

CS0522 avatar Aug 08 '24 13:08 CS0522

Yes, mimalloc has mi_manage_os_memory for this purpose:

bool mi_manage_os_memory(void* start, size_t size, bool is_committed, bool is_large, bool is_zero, int numa_node);

This will add the memory area to the mimalloc arena's from which it will allocate its memory (use numa_node=-1 for no NUMA preference). There is no need for a specific heap, just mi_malloc will work. It is best if the area is as large as possible such that mimalloc can manage it most effectively with regard to fragmentation.

Hope this helps, Daan

ps. There is also an extended api, mi_manage_os_memory_ex to reserve "exclusive" memory that can only be used with heaps attached to such memory (mi_heap_new_in_arena) but I don't think that is what you are asking? (this is used for example to implement compressed pointers in the Koka language using a 4GiB exclusive area for language allocations)

daanx avatar Aug 12 '24 20:08 daanx

Thanks very much for your help! It really does me a favor. mimalloc is very useful, and my project cannot be done without it.

CS0522 avatar Aug 14 '24 03:08 CS0522

@daanx I am a bit confused about how the mimalloc uses the process memory initially. As far as I know, when the process starts, it already reserves some memory area for the heap, and libc uses sbrk to extend.

But I can track mimalloc down, I understand that it does mmap do manage the memory, right?

Also, what is the alignment-requirement for the mimalloc?

gulmezmerve avatar Aug 16 '24 10:08 gulmezmerve

Ah, mimalloc generally does not use sbrk (as that doesn't allow returning (purging) memory back to the OS), and we try to use mmap on most unix systems. See https://github.com/microsoft/mimalloc/blob/dev/src/prim/unix/prim.c for the primitives. Mimalloc allocates it's OS memory with 4MiB alignment (on 64-bit systems).

daanx avatar Aug 22 '24 00:08 daanx

thank you for the clarification!

gulmezmerve avatar Aug 22 '24 08:08 gulmezmerve

Hi @daanx

Thank you for having responded in the issue and similar issues.

I have a similar problem to the OP, and I can't get mimalloc to allocate from the mmapped file, even with mi_reserve_os_memory...

Here's the code (I've removed sanity and error message checks for brevity)

#define FILE_SIZE (16 * 1024 * 1024) // 16MB

fd = open("mmapped_file.txt", O_RDWR | O_CREAT, 0666);
char *file_in_memory = mmap(NULL, FILE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_32BIT, fd, 0);
int reserveRet = mi_reserve_os_memory(FILE_SIZE, false, true);
int manageRet = mi_manage_os_memory(file_in_memory, FILE_SIZE, true, false, false, -1);

void *p = mi_malloc(1 * 1024 * 1024); // 1MB
void *q = mi_malloc(1 * 1024 * 1024); // 1MB
void *r = mi_malloc(1 * 1024 * 1024); // 1MB
void *s = mi_malloc(1 * 1024 * 1024); // 1MB

printf("base: %p\n", file_in_memory);
printf("p   : %p\n", p);
printf("q   : %p\n", q);
printf("r   : %p\n", r);
printf("s   : %p\n", s);

Outputs:

base: 0x40000000
p   : 0x20000000200
q   : 0x20000140200
r   : 0x20000280200
s   : 0x20000400200

How do I make sure mimalloc is using my mmapped file?

I'll try your solution in #730 next, but I'm not sure where to find MIMALLOC_RESERVE_OS_MEMORY or MIMALLOC_LIMIT_OS_ALLOC

Edit: The #730 solution didn't work either, sadly. Iused mi_reserve_os_memory_ex and mi_heap_new_in_arena as well as mi_heap_set_default and mi_heap_malloc as instructed, and they're returning valid values (no errors).

MohammadKhalaji avatar Oct 10 '24 22:10 MohammadKhalaji