Расчет размера разделяемой памяти С++

Я храню два объекта в shared memory, один из них - это класс, который:

class GlobalObj
{
public: 
    unsigned int counter;
    unsigned int label;
    bool isExist;

    Globals(void){}
    ~Globals(void){};
};

А другой - это boost::multi_index_container, который содержит объекты этого типа:

class TestObj
{   
public:
    long id;
    unsigned _int64 track1; 
    unsigned _int64 track2;
    int label;


    MetaData(void){};
    ~MetaData(void){};
};

Поэтому, когда я создаю общую память, я вычисляю размер следующим образом:

// TEST_CONTAINER_SIZE is a constant which is the 
// maximum number of record that multi_index container will keep
size_t containerSize = TEST_CONTAINER_SIZE * sizeof(TestObj);

// create shared memory         
managed_shared_memory segment(create_only,"SharedMemory", containerSize + sizeof(GlobalObj));

Поэтому, когда я устанавливаю TEST_CONTAINER_SIZE = 10000;, я ожидаю, что смогу вставить 10000 TestObj в контейнер multi_index в разделяемой памяти. Но когда я запускаю программу, она вызывает исключение, связанное с размером общей памяти в элементе 3071th.

Есть ли какие-либо накладные расходы на сам контейнер multi_index, или я упускаю что-то еще, пока вычисляю размер разделяемой памяти?

Спасибо.

ИЗМЕНИТЬ:

Итак, в моей текущей реализации мой контейнер multi_index и распределение выглядят так:

typedef multi_index_container<
    TestObj, 
        indexed_by<    
            ordered_unique<member<TestObj, long, &TestObj::id> >,
            ordered_non_unique< member<TestObj, unsigned _int64, &TestObj::track1> >
        >, 
        boost::interprocess::managed_shared_memory::allocator<TestObj>::type
> ContainerType;


segment = new managed_shared_memory(open_only, "SharedMemory");

DataContainer = segment->construct<ContainerType>
        ("DataContainer")                      //Container's name in shared memory
        ( ContainerType::ctor_args_list()
        , segment->get_allocator<TestObj>());    

Итак, поскольку я знаю, сколько предметов будет в моем контейнере, каков наиболее эффективный и стабильный способ его размещения?


person Vecihi    schedule 24.04.2014    source источник


Ответы (2)


Существует много накладных расходов на управление сегментом разделяемой памяти.

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

В этом ответе я сравнил ряд накладных расходов с managed_shared_memory:

Картинка говорит тысячу слов:

введите здесь описание изображения

Как видите, объем оставшейся памяти сильно зависит от того, как вы управляете ее распределением.

person sehe    schedule 24.04.2014
comment
Спасибо за ответ. Пожалуйста, смотрите мое редактирование. И не могли бы вы рассказать мне, как реализовать способ flat_map_reserved? - person Vecihi; 24.04.2014
comment
@Vecihi Я думаю, что код должен быть в связанном ответе. Я стараюсь всегда включать работающий код. Просто используйте вторую ветку #if (как показано в коде) - person sehe; 24.04.2014
comment
Хорошо, я попробую это и сообщу. Спасибо. - person Vecihi; 24.04.2014
comment
Обратите внимание, что вы можете использовать вызов get_free_memory(), который я использовал для определения эффективного использования памяти. Имейте в виду, что использование может не быть одинаковым каждый раз, потому что оно также зависит от шаблонов использования (фрагментация). Вот почему reserve-обработка памяти помогла. - person sehe; 24.04.2014

Это полностью зависит от реализации, вы не можете предполагать что-либо о размере контейнера. Вы, вероятно, захотите использовать пользовательский allocators с контейнером multi_index.

person Paul Evans    schedule 24.04.2014
comment
Я не понимаю, как это могло бы работать, если бы он не использовал настраиваемые распределители из boost IPC. На самом деле, тогда бы ему вообще не хватило общей памяти :) - person sehe; 24.04.2014