Код: Выделить всё
#include
#include
#include "/home/vin/jemalloc/include/jemalloc/jemalloc.h"
#include
/*
To run this test:
1. clone jemalloc: git clone https://github.com/jemalloc/jemalloc.git
2. configure jemalloc with --with-jemalloc-prefix=jem_
3. build test:
g++ -std=c++17 -I/home/user/jemalloc/include -L/home/user/jemalloc/lib test.cc -o test -ljemalloc
*/
const size_t INITIAL_MMAP_SIZE = 1ULL * 1024 * 1024 * 1024; // 1 GiB
struct ArenaInfo
{
uintptr_t base_pointer;
uintptr_t pre_alloc;
} info;
void *extent_alloc_hook_dram(extent_hooks_t *extent_hooks, void *new_addr, size_t size,
size_t alignment, bool *zero, bool *commit, unsigned arena_ind)
{
uintptr_t ret = (info.pre_alloc + alignment - 1) & ~(alignment - 1);
if (ret + size > info.base_pointer + INITIAL_MMAP_SIZE)
return nullptr;
info.pre_alloc = ret + size;
if (*zero)
memset(reinterpret_cast(ret), 0, size);
printf(">>> extent request: size %lu ret %p alignment %lu\n", size, (void *)ret, alignment);
return reinterpret_cast(ret);
}
int main()
{
extent_hooks_t *hooks = new extent_hooks_s();
memset(hooks, 0, sizeof(extent_hooks_s));
hooks->alloc = extent_alloc_hook_dram;
info.base_pointer = reinterpret_cast(mmap(NULL, INITIAL_MMAP_SIZE,
PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
if (reinterpret_cast(info.base_pointer) == MAP_FAILED)
{
std::cerr extent request: size 2097152 ret 0x7fffb7000000 alignment 4096
>>> extent request: size 4096 ret 0x7fffb7200000 alignment 4096
1024 0x7fffb7200000
1024 0x7fffb7200400
1024 0x7fffb7200800
1024 0x7fffb7200c00
>>> extent request: size 2097152 ret 0x7fffb7201000 alignment 4096
>>> extent request: size 4096 ret 0x7fffb7401000 alignment 4096
1024 0x7fffb7401000
1024 0x7fffb7401400
1024 0x7fffb7401800
1024 0x7fffb7401c00
>>> extent request: size 2097152 ret 0x7fffb7402000 alignment 4096
>>> extent request: size 4096 ret 0x7fffb7602000 alignment 4096
1024 0x7fffb7602000
1024 0x7fffb7602400
1024 0x7fffb7602800
1024 0x7fffb7602c00
>>> extent request: size 2097152 ret 0x7fffb7603000 alignment 4096
>>> extent request: size 4096 ret 0x7fffb7803000 alignment 4096
1024 0x7fffb7803000
1024 0x7fffb7803400
1024 0x7fffb7803800
1024 0x7fffb7803c00
Я ожидал, что все 1024 выделения (принадлежащие к одному и тому же классу размера) должны находиться в непрерывном блоке. После каждых 4 1024 выделений запрашивается экстент размером 2 МБ, который предположительно используется для метаданных, и, следовательно, для хранения наших выделений запрашивается экстент 4096 B. Итак, теперь вы можете видеть, как простое последовательное распределение (одного и того же класса размера) без всякой причины размещает выделения на расстоянии 2 МБ друг от друга. Я называю использование метаданных «высоким и расточительным», потому что нам не нужны 2 МБ экстента метаданных для управления одним экстентом размером 4 КиБ. В идеале я бы не ожидал запроса на экстенты размером 2 МБ до тех пор, пока не будет заполнено большое количество страниц.
Подробнее здесь: https://stackoverflow.com/questions/787 ... n-jemalloc