Сколько памяти должно выделять «managed_shared_memory»? (увеличение) - PullRequest
11 голосов
/ 12 ноября 2010

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

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

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

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

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

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

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

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

Ответы [ 2 ]

8 голосов
/ 12 ноября 2010

С данного пункта документации:

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

Расположение сегмента памяти:

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

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

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

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

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

    managed_shared_memory segment(create_only, "name", 4096);
2 голосов
/ 12 января 2011

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

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]();
...