Подтвердить что ты не робот

Сколько памяти должно "managed_shared_memory" выделять? (увеличение)

Я ищу окончательный ответ (если он действительно существует) о том, сколько памяти должно быть выделено при создании статических кусков разделяемой памяти через boost::interprocess managed_shared_memory. Даже официальные примеры, как представляется, выделяют произвольно большие куски памяти.

Рассмотрим следующую структуру:

// Example: simple struct with two 4-byte fields
struct Point2D {
  int x, y;
};

Моя первоначальная реакция заключается в том, что необходимый размер будет 8 байтов или sizeof(Point2D). Это терпит неудачу, когда я пытаюсь построить объект, давая мне seg-faults во время выполнения.

// BAD: 8 bytes is nowhere near enough memory allocated.
managed_shared_memory segment(create_only, "My shared memory", sizeof(Point2D));

Какая операция чтения/записи вызывает seg-faults? Операции стека? Временное распределение в пределах segment.construct()? Сколько накладных расходов необходимо при распределении разделяемой памяти?

В результате проб и ошибок я обнаружил, что умножение размера на 4 может работать для вышеуказанной структуры, но разваливается, когда я начинаю добавлять дополнительные поля в мой struct. Итак, это пахнет плохим взломом.

Некоторые могут утверждать, что "память дешевая" на современном ПК, но я не согласен с этой философией и не люблю выделять больше, чем мне нужно, если я могу ее избежать. Вчера я выкопал документы Boost и не нашел никаких рекомендаций. Здесь, чтобы узнать что-то новое сегодня!

4b9b3361

Ответ 1

Из настоящего параграфа документации:

Алгоритм памяти - это объект, который помещается в первые байты файл с общей памятью/памятью сегмент.

Макет сегмента памяти:

 ____________ __________ ____________________________________________  
|            |          |                                            | 
|   memory   | reserved |  The memory algorithm will return portions | 
| algorithm  |          |  of the rest of the segment.               | 
|____________|__________|____________________________________________| 

В библиотеке есть дополнительные накладные расходы памяти, расположенные в начале сегмента, таким образом, занимая несколько байтов вашего запрошенного размера. Согласно этот пост и этот пост, это точное число дополнительные байты не могут быть определены:

Вы не можете вычислить его, потому что там являются резервирование распределения памяти и проблемы фрагментации, которые время выполнения в зависимости от вашего шаблон распределения/освобождения. А также разделяемая память выделяется страницами по ОС (4K на linux 64k on окна), поэтому любое распределение будет на практике распределены округленными до страница:

    managed_shared_memory segment(create_only, "name", 20);

будет терять ту же память, что и:

    managed_shared_memory segment(create_only, "name", 4096);

Ответ 2

Работает что-то вроде использования размера страницы памяти OS'es. В моем случае это работает.

off_t size = sizeof(class1) + (sizeof(class2) * 3);
// round up to the OS page size.
long page_size = sysconf(_SC_PAGE_SIZE);
size = ((size / page_size) + (size % page_size ? 1 : 0)) * page_size;

Использование boost:: managed_shared_memory позволяет создавать объекты в полученном пространстве. Что-то вроде....

shared_memory_object::remove(m_name.c_str());
m_shared.reset(new managed_shared_memory(create_only, "myspace", size));
m_class1 = m_shared->construct<class1>("class1")();
m_class2 = m_shared->construct<class2>("class2")[3]();