我想(在*nix中)分配一个大的,有条不紊的地址空间,但不会立即消耗资源,即我想保留一个地址范围,以后再分配它.
假设我做foo = malloc(3*1024*1024*1024)来分配3G,但是在1G计算机上有1G的交换文件.它会失败,对吗?
我想要做的是说"给我一个内存地址范围foo ... foo + 3G 我将分配 ",所以我可以保证这个区域内的所有分配都是连续的,但没有直接分配.
在上面的例子中,我想跟随一个bar = malloc(123)调用的foo = reserve_memory(3G)调用,该调用应该成功,因为reserve_memory尚未消耗任何资源,它只是保证bar不在范围内烟草工业富+ 3G.
稍后我会做一些像allocate_for_real(foo,0,234)那样消耗foo范围的字节0..234.此时,内核将分配一些虚拟页面并将它们映射到foo ... foo + 123 + N.
这在用户空间是否可行?
(关键在于foo中的对象需要连续,并且在创建后无法合理地移动.)
谢谢.
将 OSX/iOS 中的虚拟内存系统行为与 Windows 中的虚拟内存系统行为进行比较时,我有点困惑。Windows VirtualAlloc() 相关函数及其在保留和实际内存提交和取消提交方面的行为是相当简单的。
对于没有很好讨论的 OSX,我一直在研究 mach_vm_allocate()、mach_vm_map() 等。例如,如果我想创建一组跨平台函数来公开 Windows 和 OSX/iOS 之间的公共虚拟内存功能,我将如何管理与 Windows 相比,OSX 上的提交/取消提交之间的区别?
因为我不确定我是否理解您是否可以保留虚拟地址范围并将其作为像在 Windows 上一样的单独操作提交?根据我的理解,mach_vm_allocate() 类似于 VirtualAlloc() 和 MEM_COMMIT | MEM_RESERVE 并尝试比较哪个实际上是设计更好的机制(如果有的话)。
可能我需要更好地了解页面管理器在 OSX 中的功能。
在 Windows 上,即使您提交了一个区域,我怀疑它可能实际上并没有用物理内存支持它,直到您尝试访问它,除非当前可能有足够的内存 - 并且它只是保证在修改时支持交换文件。
在 OSX 上,我不确定如何取消提交区域但仍保留地址范围?例如,这种行为在 64 位程序中很有用(我最感兴趣的是)为具有回滚能力的竞技场/堆栈/线性分配器保留一个大的虚拟地址范围——这需要能够提交和取消提交区域的末端。在 Windows 中很明显如何产生这种行为,但在 OSX 中我不太明白如何有效地复制它。
编辑:
我刚刚发现了这个:
这与我的问题有关,但肯定 mmap() 经历了等效的 mach_vm_*() 系统调用?
编辑2:
典型的我现在发现这些:
带有 MAP_NORESERVE 的 mmap 是否保留物理内存?
但它可能仍然没有弄清楚如何以我想要的方式取消提交 - 但是去谷歌更多关于 mmap() ANON 的东西 - 并可能看看我是否可以找到 OSX 的 mmap() 源代码( …
首先,让我说我非常了解VirtualAlloc()现代操作系统的虚拟内存设施是如何工作的,一般来说是如何工作的。
说,使用Windows API的MAP_RESERVE标志VirtualAlloc(),不使用也MEM_COMMIT,今天有一些实际用途吗?
我的意思是,当我打电话VirtualAlloc()跟MEM_RESERVE|MEM_COMMMIT我都保存和提交页面,但我知道,操作系统将真正分配页面,只有当我尝试写放进去。这种优化几乎发生在所有现代操作系统上。
因此,这种优化的头脑,如果我叫VirtualAlloc()用MEM_RESERVE,然后我把它叫做几次MEM_COMMIT提交页面,是不是同一调用的结果VirtualAlloc()只有一次,指定MEM_RESERVE|MEM_COMMIT?
既然指定只MEM_RESERVE保留页边界地址,不提交真实页,那么MEM_RESERVE|MEM_COMMIT只保留+提交我写的页,不是MEM_RESERVE单独使用,今天浪费时间吗?由于只有1呼吁VirtualAlloc()与MEM_RESERVE|MEM_COMMIT我基本上能获得调用的结果相同VirtualAlloc()1周时间MEM_RESERVE,并调用了好N倍MEM_COMMIT。
作为我所说的证据,我注意到MEM_RESERVE在使用mmap(2)系统调用的Unices/POSIX 系统中根本不存在该工具。此外,您可以在那里“提交”一大块页面调用mmap(2)一次,然后只有在您写入页面时才会真正分配页面,所有页面均由操作系统优化。
那么,MEM_RESERVE只有当内存页是一种宝贵的资源时,单独使用只是过去的事情才有用,所以今天没有用吗?或者,单独使用这个标志(然后用 调用VirtualAlloc()N 次MEM_COMMIT)仍然有一些我缺少的实际用途?