c++ - Why does an object allocated in boost interprocess shared memory take up more memory than required? -


for below program using boost interprocess shared memory,

#include <iostream> #include <boost/interprocess/mapped_region.hpp> #include <boost/interprocess/managed_shared_memory.hpp> #include <boost/interprocess/containers/list.hpp> #include <iostream>  #define shared_memory_name "so12439099-mysharedmemory" #define dataoutput "outputfromobject" #define initial_mem 650000 #define state_matrix_size 4  using namespace std; namespace bip = boost::interprocess;   class sharedobject { public:     unsigned int tnumber;     bool prcvdflag;     bool srcvdflag;     unsigned long ltimestamp;  };  typedef bip::allocator<sharedobject, bip::managed_shared_memory::segment_manager> shmemallocator; typedef bip::list<sharedobject, shmemallocator> sharedmemdata;    int main() {         bip::managed_shared_memory* seg;         sharedmemdata *sharedmemoutputlist;          bip::shared_memory_object::remove(dataoutput);         seg = new bip::managed_shared_memory(bip::create_only, dataoutput, initial_mem);         const shmemallocator alloc_inst(seg->get_segment_manager());         sharedmemoutputlist = seg->construct<sharedmemdata>("trackoutput")(alloc_inst);          std::size_t beforeallocation = seg->get_free_memory();         std::cout<<"\nbefore allocation = "<< beforeallocation <<"\n";         sharedobject temp;         sharedmemoutputlist->push_back(temp);         std::size_t afterallocation = seg->get_free_memory();         std::cout<<"after allocation = "<< afterallocation <<"\n";                 std::cout<<"difference = "<< beforeallocation - afterallocation <<"\n";                 std::cout<<"size of sharedobject = "<< sizeof(sharedobject) <<"\n";            std::cout<<"size of sharedobject's temp instance = "<< sizeof(temp) <<"\n";                    seg->destroy<sharedmemdata>("trackoutput");         delete seg;             }//main 

the output is:

before allocation = 649680 after allocation = 649632 difference = 48 size of sharedobject = 16 size of sharedobject's temp instance = 16 

if size of sharedobject , it's instance 16 bytes, how can difference in allocation 48? if padding had automatically been done, it's still account 3 times size (for larger structures goes 1.33 times size).
because of this, i'm unable allocate , dynamically grow shared memory reliably. if sharedobject contains list grows dynamically, add uncertainty of space allocation more.

how can these situations safely handled?

ps: run program, have link pthread library , librt.so.

update:

this memory usage pattern got when tabulated values multiple runs (the memory increase column current row of memory used column minus previous row of memory used column):

╔═════════════╦════════════════╦═════════════════╗
║      memory used       ║ structure size                     ║ memory increase                 ║
╠═════════════╬════════════════╬═════════════════╣
║                               48 ║                                         1 ║                                              ║
║                               48 ║                                         4 ║                                           0 ║
║                               48 ║                                         8 ║                                           0 ║
║                               48 ║                                       16 ║                                           0 ║
║                               64 ║                                       32 ║                                         16 ║
║                               64 ║                                       40 ║                                           0 ║
║                               80 ║                                       48 ║                                         16 ║
║                               96 ║                                       64 ║                                         32 ║
║                             160 ║                                     128 ║                                         64 ║
║                             288 ║                                     256 ║                                       128 ║
║                             416 ║                                     384 ║                                       128 ║
║                             544 ║                                     512 ║                                       128 ║
║                             800 ║                                     768 ║                                       256 ║
║                           1056 ║                                   1024 ║                                       256 ║
╚═════════════╩════════════════╩═════════════════╝

important: above table applies shared memory list. vector, (memory used, structure size) values = (48, 1), (48, 8), (48, 16), (48, 32), (80, 64), (80, 72), (112, 96), (128, 120), (176, 168), (272, 264), (544, 528).
different memory calculation formula needed other containers.

remember general purpose allocation mechanism has payload in order store information how deallocate memory, how merge buffer adjacent buffers, etc.. happens system malloc (typically, 8-16 bytes per allocation plus alignment). memory allocator in shared memory has overhead of 4-8 bytes (in 32 bits systems, 8-16 in 64 bit systems)

then library needs store number of objects in order call destructors when calling "destroy_ptr(ptr)" (you can allocate arrays, need know how many destructors shall called). , you've made named allocation, library needs store string in shared memory , metadata find (a pointer string , maybe "named allocation" , not "anonymous" or "instance allocation).

so 16 bytes of data + 8 bytes memory allocator + 8 bytes store pointer+metadata name + 12 bytes string "trackoutput" (including null-end) plus alignment 8 bytes, 48 bytes.

the overhead constant each allocation. constant factor 1.33 applies small allocations. if allocate single byte you'll worse factors, if allocate single char heap.

the library throws exception if there not available memory store new object, can catch , try create new managed shared memory. note memory gets fragmented allocations , reallocations, free bytes in shared memory, managed shared memory not service request because there no contiguous memory big enough fulfill it. shared memory can't automatically expanded fragmentation bigger issue heap memory.

you can't dynamically grow shared memory other process might connected , crash trying access unmapped pages. alternative preallocate shared memory enough adding constant padding factor or allocate new managed shared memory , notify other readers/writers (maybe using prealocated structure in original shared memory) new elements go in new managed shared memory.


Comments

Popular posts from this blog

Magento/PHP - Get phones on all members in a customer group -

php - .htaccess mod_rewrite for dynamic url which has domain names -

Website Login Issue developed in magento -