Сколько памяти должно "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 и не нашел никаких рекомендаций. Здесь, чтобы узнать что-то новое сегодня!
Ответы
Ответ 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]();