【发布时间】:2014-03-15 13:37:55
【问题描述】:
在将 OSX/iOS 中的虚拟内存系统行为与 Windows 进行比较时,我有点困惑。 Windows VirtualAlloc() 相关函数及其与保留和实际内存提交和取消提交有关的行为非常简单。
对于没有得到很好讨论的 OSX,我一直在研究 mach_vm_allocate()、mach_vm_map() 等。例如,如果我想创建一组跨平台函数来公开 Windows 和 OSX/iOS 之间的通用虚拟内存功能,如何我会管理 OSX 上的提交/取消提交与 Windows 上的区别吗?
我不确定我是否理解您是否可以保留虚拟地址范围并将其作为单独的操作提交,就像在 Windows 上一样?据我了解, mach_vm_allocate() 类似于带有 MEM_COMMIT | 的 VirtualAlloc() MEM_RESERVE 并尝试比较哪个实际上是一个更好的设计机制,如果有任何令人困惑的话。
可能我需要更好地了解页面管理器在 OSX 中的功能。
在 Windows 上,即使您提交了一个区域,我怀疑它实际上可能不会用物理内存支持它,除非您尝试访问它,除非当前可能有充足的内存 - 并且它只是保证在修改时交换文件支持。
在 OSX 上,我不确定如何取消提交区域但仍保留地址范围?例如,这种行为在 64 位程序(我最感兴趣)中很有用,可以为具有倒带能力的竞技场/堆栈/线性分配器保留一个大的虚拟地址范围 - 这需要能够提交和取消提交区域的末端。在 Windows 中,如何产生这样的行为是显而易见的,但在 OSX 中,我不太了解如何有效地复制它。
编辑:
我刚刚发现了这个:
这与我的问题有关但是 mmap() 肯定会通过等效的 mach_vm_*() 系统调用?
编辑2:
我现在发现这些是典型的:
Does mmap with MAP_NORESERVE reserve physical memory?
How can I reserve virtual memory in Linux?
但它可能仍然没有弄清楚如何以我想要的方式取消提交 - 但要在 mmap() ANON 上搜索更多内容 - 并可能看看我是否能找到 mmap() 源代码对于 OSX (?)。
(如果我能弄清楚解除提交问题,肯定有人会说使用 mmap() 因为它也可以在 linux 上工作,但我仍然很好奇它是如何通过 mach_vm_*() 调用路由的......)
EDIT3:
我发现 mremap() 和 mmap() 一起看起来很有用!显然,使用 PROT_NONE、MAP_NORESERVE 和 mmap() 看起来也很有趣。但是我仍然不确定如何取消提交区域但仍然保留地址范围,因为 mremap() 似乎无法使用 MAP_NORESERVE 来放弃交换文件支持?
EDIT4:
我发现这与取消提交有关:https://bugzilla.mozilla.org/show_bug.cgi?id=670596。其中讨论了 OSX 和 Linux 上关于 mprotect(addr, len, PROT_NONE) 和 madvise() 的行为。 ..
EDIT5:(!)
挖掘我为 madvise() 找到的 Mac 头文件:
#define MADV_WILLNEED POSIX_MADV_WILLNEED
#define MADV_DONTNEED POSIX_MADV_DONTNEED
#define MADV_FREE 5 /* 不需要的页面,丢弃内容 */
#define MADV_ZERO_WIRED_PAGES 6 /* 将条目删除前尚未取消连线的连线页面归零 */
#define MADV_FREE_REUSABLE 7 /* 页面可以重复使用(任何人)*/
#define MADV_FREE_REUSE 8 /* 调用者想要重用这些页面 */
#define MADV_CAN_REUSE 9
所以我猜 MADV_FREE_REUSE 应该是取消提交的首选用法?
EDIT6:我在 iOS/OSX 开发者论坛上提出了这个问题,与此同时,我遇到了这些问题,这些问题可能对其他想同样问题的人有所帮助:
http://lists.apple.com/archives/PerfOptimization-dev/2009/Apr/msg00024.html http://markmail.org/message/yqwqd3zuawz6v5dd
还有这个:
http://fxr.watson.org/fxr/source/bsd/kern/kern_mman.c?v=xnu-1228;im=bigexcerpts#L824
似乎关键是 mmap() 和 madvise(),或者带有标志 VM_BEHAVIOR_DONTNEED 的 mach_vm_allocate() 和 mach_vm_behavior_set()。
在试验后会为他人的利益报告...
EDIT7:
mmap() 和 madvise() 目前最新的 OSX 10.9 源代码我认为:http://www.opensource.apple.com/source/xnu/xnu-2422.1.72/bsd/kern/kern_mman.c
似乎确认了mach_vm_behavior_set()
EDIT8:
据我所知,现在可以从 OSX 10.9 得知:
http://www.opensource.apple.com/source/xnu/xnu-2422.1.72/osfmk/vm/vm_map.c
我应该使用 mach_vm_allocate() 和 vm_map_behavior_set() 与 Windows VirtualAlloc() 用语中的(暗示性)标志大致相同:
VM_BEHAVIOR_WILLNEED => Commit address range
VM_BEHAVIOR_DONTNEED => Decommit address range
VM_BEHAVIOR_FREE => Decommit and completely release address range(?)
但我不确定这些到底是什么意思(?):
VM_BEHAVIOR_REUSABLE
VM_BEHAVIOR_REUSE
VM_BEHAVIOR_CAN_REUSE
我希望得到苹果公司对首选使用模式的确认,但我想我已经接近用上述方法回答我自己的问题了......
这是我第一次有幸挖掘一些非常干净的开源代码:-)
【问题讨论】:
标签: c windows macos memory virtual