繁体   English   中英

制作自己的malloc功能?

[英]making your own malloc function?

我读到有些游戏会重写自己的malloc以提高效率。 我不明白在虚拟内存世界中这是如何实现的。 如果我没记错的话,malloc实际上调用了一个特定于操作系统的功能,它将虚拟地址映射到MMU的真实地址。 那么,如何在不调用实际运行时的malloc的情况下,如何制作自己的内存分配器并分配实内存?

谢谢

编写一个比一般用途更有效的分配器当然是可能的。

如果您知道分配的属性,则可以将通用分配器从水中吹出。

举个例子:多年前,我们不得不为嵌入式系统设计和编写通信子系统(HDLC,X.25和专有层)。 事实上,我们知道最大分配总是小于128个字节(或类似的东西)意味着我们根本不需要使用可变大小的块。 无论您要求多少, 每个分配都是128个字节。

当然,如果你要求更多,它返回NULL。

通过使用固定长度的块,我们能够大大加快分配和解除分配,使用位图和相关结构来保存记帐信息,而不是依赖于较慢的链接列表。 此外,不需要合并释放的块。

当然,这是一个特例,但你会发现游戏也是如此。 事实上,我们甚至在一个通用系统中使用它,在这个系统中,低于某个阈值的分配从自我管理的预分配池中以相同的方式获得固定数量的内存。 任何其他分配(大于阈值或池完全分配)都被发送到“真正的” malloc

仅仅因为malloc()是一个标准的C函数并不意味着它是你对内存系统的最低级别访问。 实际上, malloc()可能是根据较低级别的操作系统功能实现的。 这意味着你也可以调用那些低级接口。 它们可能是特定于操作系统的,但它们可能会比您从malloc()接口获得更好的性能。 如果是这种情况,您可以按照自己的方式实现自己的内存分配系统,并且可能更加高效 - 根据您要进行的分配大小和频率的特性优化算法,例如。

通常,malloc将调用特定于OS的函数来获取一堆内存(至少一个VM页面),然后根据需要将该内存划分为更小的块以返回到malloc的调用者。

malloc库还将包含一个(或列表)空闲块,因此它通常可以满足请求,而无需向操作系统请求更多内存。 确定要处理多少个不同的块大小,决定是否尝试组合相邻的空闲块等等,是malloc库实现者必须做出的选择。

您可以绕过malloc库并直接调用操作系统级别“给我一些内存”功能,并在您从操作系统获得的内存中自行分配/释放。 此类实现可能是特定于操作系统的。 另一种方法是使用malloc进行初始分配,但保留自己的已释放对象缓存。

您可以做的一件事是让您的分配器分配一个内存池,然后分配来自的服务请求(如果它用完,则分配一个更大的池)。 我不确定这是不是他们正在做的事情。

如果我没记错的话,malloc实际上调用了一个OS特定的函数

不完全的。 大多数硬件的页面大小为4KB。 操作系统通常不公开提供小于页面大小(和页面对齐)块的任何内容的内存分配接口。

malloc花费大部分时间来管理已经分配的虚拟内存空间,并且偶尔会从操作系统请求更多内存(显然这取决于您分配的项目的大小以及您free频率)。

有一种常见的误解,即当你free某些东西时,它会立即返回到操作系统。 虽然这有时会发生(特别是对于较大的内存块),通常情况下, free d内存仍然分配给进程,然后可以被后来的malloc重用。

因此,大部分工作都是在已经分配的虚拟空间的簿记中。 分配策略可以有许多目标,例如快速操作,低内存浪费,良好的局部性,动态增长空间(例如realloc )等。

如果您对内存分配和发布模式有更多了解,可以针对您的使用模式优化mallocfree使用,或者提供更广泛的界面。

例如,您可能正在分配大量相等大小的对象,这可能会更改最佳分配参数。 或者你可能总是一次释放大量的物品,在这种情况下你不想free地做任何花哨的事情。

看看内存池障碍物

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM