首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >更有效地使用fork()和复制上写内存共享。

更有效地使用fork()和复制上写内存共享。
EN

Stack Overflow用户
提问于 2012-03-24 11:02:03
回答 1查看 868关注 0票数 7

我是一个程序员,使用基于Linux的服务器开发一个多人在线游戏。我们为我们的世界使用了一种“实例”架构。这意味着每个进入世界区域的玩家都会得到该区域的副本,与他们的党员一起玩,并且独立于在同一区域玩的所有其他玩家。

在内部,我们对每个实例使用一个单独的进程。最初,每个实例进程都会启动,只加载给定区域所需的资源,生成它的随机地形,然后允许玩家进行新的连接。实例使用的内存量通常约为25 meg,包括资源和与实体随机生成的级别。

为了减少实例的内存占用,并加快生成时间,我们改变了一种方法,在这种方法中,我们创建一个主实例,它加载任何实例可能需要的所有资源(大约150 meg内存),然后当需要一个新实例时,使用fork()函数生成一个新实例,并使用复制到写上的内存共享,这样新实例只需要为它的“唯一”数据集使用内存。组成每个实例的唯一数据的随机生成的级别和实体的占用空间约为3-4 meg内存。

不幸的是,内存共享没有我想的那么好。许多内存页似乎变得无人共享。

首先,当我们在预叉实例中加载更多的数据集时,每个分叉实例所需的内存就会减少,但最终会出现一个拐点,在预叉中加载更多的资产实际上会增加每个已分叉实例使用的数据。

我们所得到的最佳结果是加载大约80 meg的数据集预分叉,然后让新实例要求加载其余的数据集。这导致约7-10兆克每例和80兆克固定成本.当然是一个很好的改进,但不是理论上最好的。

如果我加载整个150 meg数据集,然后叉,每个分叉实例使用大约50梅格的内存!比什么都不做更糟糕。

我的问题是,如何在预叉实例中加载所有数据集,并确保只获取每个实例的最小唯一数据集作为每个实例的内存占用量。

我对这里正在发生的事情有一个理论,我想知道是否有人能帮我证实这是事实。

我想这和马洛的自由链有关。预叉实例的每个内存页可能都保留了一些空闲的内存点。如果在随机级别生成过程中,分配了一些恰好适合页面中某个空闲点的内容,那么整个页面将被复制到分叉过程中。

在windows中,您可以创建备用堆,并更改进程使用的默认堆。如果这是可能的话,它将消除问题。在linux中有什么办法做这样的事情吗?我的调查似乎表明你不能。

另一个可能的解决方案是,如果我可以以某种方式放弃现有的malloc空闲链,迫使malloc从操作系统中为后续调用分配新的内存。我试图查看malloc的实现,看看这是否容易实现,但它似乎有点复杂。如果有人对这一领域有任何想法或建议,我很想听听。

最后,如果有人对这里可能出了什么问题有其他想法的话,我真的很想听听。非常感谢!

EN

回答 1

Stack Overflow用户

发布于 2012-03-24 11:04:56

在windows中,您可以创建备用堆,并更改进程使用的默认堆。如果这是可能的话,它将消除问题。在linux中有什么办法做这样的事情吗?

I-您可以简单地使用mmap(2)内存,完全绕过malloc

我也会抛弃所有的“靠牛”的东西。我会让主进程mmap有一些内存(80米,150米任何东西),给它写一些东西,把它标记出来--只通过mprotect(2)进行读--以便有好的测量,然后从那里取出来。这将解决真正的问题,也不会强迫你在未来的道路上修改代码。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9851201

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档