如何在不分配内存的情况下保留内存地址

12

我希望(在*nix中)分配一个大的、连续的地址空间,但是不立即消耗资源,也就是说,我想要预留一段地址范围,稍后再从中分配。

假设我执行foo=malloc(3*1024*1024*1024)来分配3G,但在1G计算机上,只有1G的交换文件。这会失败,对吧?

我想做的是说“给我一个内存地址范围foo...foo+3G,我将在其中进行分配”,以便我可以保证该区域内的所有分配都是连续的,但实际上并没有直接分配。

在上面的例子中,我想用foo=reserve_memory(3G)调用后跟随bar=malloc(123)调用,因为reserve_memory尚未消耗任何资源,所以应该成功,它仅仅是保证bar不会在范围foo...foo+3G内。

稍后我会执行allocate_for_real(foo,0,234),以消耗foo范围内的0到234字节。此时,内核将分配一些虚拟页面,并将它们映射到foo...foo+123+N。

这在用户空间中是否可行?

(这样做的目的是需要foo...中的对象是连续的,创建后不能合理地移动。)

谢谢。


希望你使用的是64位平台,否则3G块分配可能无法成功。 - MarkR
虚拟或物理连续的? - shodanex
2个回答

14

简短回答:它已经按这种方式工作了。

稍微详细一点的回答:坏消息是没有特殊的方法来保留一个范围而不分配它。然而,好消息是当你分配一个范围时,Linux 实际上并没有为其分配内存,而只是为你预留了该范围,以便以后使用。

Linux 的默认行为是始终接受新的内存分配,只要还有剩余地址空间。但是,当你开始使用内存时,最好有一些内存或至少有交换空间来支持它。如果没有,内核将杀死一个进程以释放内存,通常是分配最多内存的进程。

因此,在 Linux 中,默认设置下的问题从“我可以分配多少”转变为“我可以分配多少内存,之后仍然能够正常运行?”

这里有一些相关信息。


知道这个很好。你能告诉我如何找到相关文档吗? - spraff

0

我认为,一个简单的方法是使用一个大的static数组。

在任何现代系统上,除非您真正访问它,否则它不会被映射到现有内存(在磁盘上的可执行文件或执行机器的RAM中)。一旦您访问它(并且系统有足够的资源),它将神奇地初始化为所有零。

当您达到物理内存限制时,您的程序将严重减速,如果您用光了交换空间,则会随机崩溃。


一个大的静态数组也可以,malloc 也可以,最终效果是一样的。 - Prof. Falken

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接