Memory allocator offer

I have a multi-threaded section where threads should allocate several large data segments, say ~ 100 MB each, for use as buffers. Moreover, buffers may need to be resized several times during runtime.

A natural solution is to use realloc , but it can move memory that is not needed. free/malloc A couple to resize a buffer that I'm afraid of can lead to fragmentation and memory storage before the hand creates other problems.

What can I use instead to allocate / reallocate memory?

+6
source share
3 answers

Use free and malloc . This will NOT lead to fragmentation problems.

Modern allocators are quite resistant to memory fragmentation. Today, a rather pathological program is required to solve the problems of fragmentation. Fragmentation was a more serious problem when our programs directly accessed physical RAM, but with virtual memory a large β€œhole” in the program heap did not need to consume any resources.

In addition, due to the size of the buffers, most allocators will request a dedicated area from the kernel for each buffer. On Linux / OS X / BSD, this means anonymous mmap behind the scenes for each buffer. This can lead to fragmentation of the address space, but the virtual address space is mostly free for a 64-bit system, and several hundred megabytes is also not a problem in the 32-bit version.

So use free and malloc .

Alternative:. You may be lucky enough to make each buffer larger than you need. The malloc method works on modern Unix, on any pages that you don’t write, so as not to consume memory.

So, if you malloc buffer 500 MB, but use only the first 100 MB, your program does not actually use more memory than if you malloc 100 MB buffer and used all this. Thus, you get more fragmentation of the address space, but this is not a problem in 64-bit systems, and you can always adjust the distribution size to work on 32-bit systems.

Regarding suggestions for using mmap , just think of malloc / free as a simpler interface to mmap / munmap , which is for large distributions (1 MiB is a common threshold).

+5
source

Just use realloc . In a modern system, even if the buffer moves to a new address, this will happen by manipulating the page tables (on Linux, mremap , I am sure that other systems have a similar mechanism), and not by copying the data. (Note that I accept large buffers, for small buffers, usually less than a few hundred kilobytes, the actual copy will occur.)

If your goal is 64-bit machines, there is absolutely no need to worry about memory fragmentation. You will never fragment memory enough to run out of virtual address space. If you need to handle 32-bit machines as well, you'll probably be safe if you don't have too many threads. As long as the total memory consumption is less than 1 GB, due to fragmentation, due to fragmentation, it would be very difficult to break out of the virtual address space. If you are worried about this, simply predefine the largest size you may need.

+4
source

Deploy your solution with malloc / realloc / free and profile it. If memory allocation is a problem, you can use a better malloc implementation like facebook jemalloc or google tcmalloc .

See C ++ Memory Allocation Engine Performance Comparison (tcmalloc vs. jemalloc) for a comparison of the two.

They both do very well with internal / external fragmentation.

+1
source

Source: https://habr.com/ru/post/916308/


All Articles