iam*_*iam 5 c memory windows macos virtual
将 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() 源代码( ?)。
(当然有人会说使用 mmap() 因为它也适用于 linux,如果我能找出取消提交的问题,但我仍然很好奇它是如何通过 mach_vm_*() 调用路由的......)
编辑3:
我发现 mremap() 与 mmap() 一起看起来很有用!显然,使用 PROT_NONE、MAP_NORESERVE 和 mmap() 看起来也很有趣。但是我仍然不确定如何取消提交区域但仍然保留地址范围,因为 mremap() 似乎无法采用 MAP_NORESERVE 来放弃交换文件支持?
编辑4:
我发现这与取消提交有关:https : //bugzilla.mozilla.org/show_bug.cgi? id =670596。其中讨论了 OSX 和 Linux 上关于 mprotect(addr, len, PROT_NONE) 和 madvise() 的行为。..
编辑5:(!)
挖掘我为 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()。
将在试验后为他人的利益回报......
编辑7:
我认为目前最新的 OSX 10.9 源代码 mmap() 和 madvise():http : //www.opensource.apple.com/source/xnu/xnu-2422.1.72/bsd/kern/kern_mman.c
似乎确认了 mach_vm_behavior_set()
编辑8:
好吧,据我所知,从 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(?)
Run Code Online (Sandbox Code Playgroud)
但我仍然不确定这些到底是什么意思(?):
VM_BEHAVIOR_REUSABLE
VM_BEHAVIOR_REUSE
VM_BEHAVIOR_CAN_REUSE
Run Code Online (Sandbox Code Playgroud)
我希望得到苹果对首选使用模式的确认,但我想我已经接近用上述内容回答我自己的问题了......
这是我第一次有幸挖掘一些非常干净的开源代码:-)
没有确切的模拟。在 Unix 风格的操作系统中,可以访问分配的内存,这将导致它与物理内存或交换区关联。但并不总是保证分配的内存有足够的交换文件空间为其预留。因此,如果系统无法交换其他内容以释放 RAM,则系统可能无法关联物理内存。
两者vm_allocate()
都mmap()
保留一个地址范围。它们还使得进程访问该范围内的地址是合法的,此时页面将在必要时映射到物理内存。然而,在 OS X 上,我不认为这两个函数会为地址范围保留后备存储(交换)。
如果您分配一些空间然后访问它,导致它被映射到 RAM 或交换区,并且您希望将其返回到刚刚分配的状态,但清除 RAM 或交换区中的支持,我相信第二次调用 with 会做到mmap()
这MAP_FIXED
一点。