问题 应该'managed_shared_memory'分配多少内存? (促进)


我正在寻找一个明确的答案(如果确实存在),在创建静态的共享内存块时应分配多少内存 boost::interprocessmanaged_shared_memory。甚至 官方的例子 似乎分配 任意大 大块的记忆。

考虑以下结构:

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

我最初的反应是必要的大小是8个字节,或者 sizeof(Point2D)。当我尝试构造一个对象时,这会失败,在运行时给出了seg-fault。

// 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文档中挖了一遍,找不到任何建议。这是今天要学习新东西的!


12392
2017-11-12 16:14


起源

人们可能在这里不同意我的观点,但我的生活中从来没有编写过“记忆很便宜”的字样。与以往相比,购买内存并不一定非常昂贵,但它非常像金钱。你拥有的越多,你花的就越多。我为我的计算机购买的每次内存升级,我现在已经快速完成了我可以“运行更多的东西”。我一直试图在这方面保守地编码,因为它不一定便宜 为我的申请。无论如何,只是我的2c :) - Moo-Juice
我同意100%!那就是 整个 我问这个问题的原因。我只是在那里抛出那个评论来劝阻任何人说“谁在乎,只需分配1k并完成它”。我会尽力在帖子中说清楚。 - Courtney Christensen
啊好吧:)“有些人可能会说”好多了! - Moo-Juice


答案:


这一段 文件:

内存算法是一个对象   放在a的第一个字节中   共享内存/内存映射文件   分割。

内存段的布局:

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

该库在段的开头有一个额外的内存开销,因此占用了所请求大小的几个字节。根据 这个帖子 和 这个帖子,这个确切的附加字节数无法确定:

你无法计算它,因为那里   是内存分配bookeeping和   变化的碎片问题   运行时取决于你的   分配/解除分配模式。和   共享内存由页面分配   通过操作系统(Linux on 64k上的4K)   windows),所以任何分配都会   在实践中分配四舍五入到   页:

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

会浪费同样的记忆:

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

8
2017-11-12 16:54



找到那个老帖子干得好;我搜了好一会儿,然后干了。所以,“确实”是指你的意思 没有具体的答案? 这就是我从IonGaztañaga的回应中得到的结果......另外,感谢Boost文档的链接。内存映射ASCII艺术有所帮助,虽然我没有运气以编程方式确定 memory algorithm + reserved。但最终,由于我的实际实施存储了5-10个结构实例(Gaztañaga也提到),因此这是一个有争议的问题。尽管如此,这似乎是一个有效的问题,即使它主要是“学术性的”。 - Courtney Christensen
啊, 那里 我们去。我知道操作系统页面大小必须是相关的细节;上面的引用证实了我的怀疑。它似乎是“最佳猜测”分配必须要做的事情。再次感谢。 - Courtney Christensen


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

2
2018-01-12 01:33



+1我喜欢四舍五入到系统页面大小的想法。但是,它仍然看起来像我们正在创建一个 任意数量的填充。在这种情况下“3” - 三次 sizeof(class2)。我对么?我已经转移到其他项目,但我仍然对以最少的浪费分配共享内存的最佳方式感兴趣。 - Courtney Christensen
无论如何,我无法看到使用共享内存区域的页面大小。 (修正了第二位代码中的错误。)但是,您可以在共享内存区域内的第二位代码中执行我正在使用的子分配类型。看着 en.highscore.de/cpp/boost/... 可以很好地了解子分配的多种方式。我最好学习这个编辑器,这样我就可以更干净地联系 叹 - lprent