将 OSX/iOS 中的虚拟内存系统行为与 Windows 中的虚拟内存系统行为进行比较时,我有点困惑。 Windows VirtualAlloc() 相关函数及其在保留和实际内存提交和取消提交方面的行为相当简单。
对于没有很好讨论的 OSX,我一直在研究 mach_vm_allocate()、mach_vm_map() 等。例如,如果我想创建一组跨平台函数来公开 Windows 和 OSX/iOS 之间的公共(public)虚拟内存功能,我将如何管理与 Windows 相比,OSX 上的提交/取消提交之间的区别?
因为我不确定我是否理解您是否可以保留虚拟地址范围并将其作为像在 Windows 上一样的单独操作提交?根据我的理解,mach_vm_allocate() 类似于 VirtualAlloc() 和 MEM_COMMIT | MEM_RESERVE 并尝试比较哪个实际上是设计更好的机制(如果有的话)。
可能我需要更好地了解页面管理器在 OSX 中的功能。
在 Windows 上,即使您提交了一个区域,我怀疑它可能实际上并没有用物理内存支持它,直到您尝试访问它,除非当前可能有足够的内存 - 并且它只是保证在修改时支持交换文件。
在 OSX 上,我不确定如何取消提交区域但仍保留地址范围?例如,这种行为在 64 位程序中很有用(我最感兴趣的是)为具有回滚能力的竞技场/堆栈/线性分配器保留大的虚拟地址范围 - 这需要能够提交和取消提交区域的末端。在 Windows 中很明显如何产生这种行为,但在 OSX 中我不太明白如何有效地复制它。
编辑:
我刚刚发现了这个:
Reserve memory on OS X
这与我的问题有关,但肯定 mmap() 经历了等效的 mach_vm_*() 系统调用?
编辑2:
典型的我现在发现这些:
Does mmap with MAP_NORESERVE reserve physical memory?
How can I reserve virtual memory in Linux?
但它可能仍然没有弄清楚如何以我想要的方式取消提交 - 但是去谷歌更多关于 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:
目前最新的用于 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()
编辑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(?)
VM_BEHAVIOR_REUSABLE
VM_BEHAVIOR_REUSE
VM_BEHAVIOR_CAN_REUSE
最佳答案
我在 OS X 和 iOS 上使用以下方法:
char* m_base = 0;
unsigned m_offset = 0;
unsigned MAX_SIZE = 1024 * 1024 * 10; // 10 Mb
kern_return_t err = vm_allocate(mach_task_self(), (vm_address_t*)&m_base, MAX_SIZE, VM_FLAGS_ANYWHERE);
size = (size + roundToPageSize - 1) & ~(roundToPageSize - 1);
char* address = m_base + m_offset;
kern_return_t err = vm_allocate(mach_task_self(), (vm_address_t*)&address, size, VM_FLAGS_FIXED|VM_FLAGS_OVERWRITE);
m_offset += size;
// now address points to allocated memory in reserved space
size = (size + roundTo - 1) & ~(roundTo - 1);
char* address = m_base + m_offset - size;
kern_return_t err = vm_deallocate(mach_task_self(), (vm_address_t)address, size);
m_offset -= size;
kern_return_t err = vm_deallocate(mach_task_self(), (vm_address_t)m_base, MAX_SIZE);
m_base = 0;
m_offset = 0;
关于c - OSX/iOS 上的虚拟内存与 Windows 提交/保留行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21809072/
作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代
我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0
我的最终目标是安装当前版本的RubyonRails。我在OSXMountainLion上运行。到目前为止,这是我的过程:已安装的RVM$\curl-Lhttps://get.rvm.io|bash-sstable检查已知(我假设已批准)安装$rvmlistknown我看到当前的稳定版本可用[ruby-]2.0.0[-p247]输入命令安装$rvminstall2.0.0-p247注意:我也试过这些安装命令$rvminstallruby-2.0.0-p247$rvminstallruby=2.0.0-p247我很快就无处可去了。结果:$rvminstall2.0.0-p247Search
我想设置一个默认日期,例如实际日期,我该如何设置?还有如何在组合框中设置默认值顺便问一下,date_field_tag和date_field之间有什么区别? 最佳答案 试试这个:将默认日期作为第二个参数传递。youcorrectlysetthedefaultvalueofcomboboxasshowninyourquestion. 关于ruby-on-rails-date_field_tag,如何设置默认日期?[rails上的ruby],我们在StackOverflow上找到一个类似的问
我将我的Rails应用程序部署到OpenShift,它运行良好,但我无法在生产服务器上运行“Rails控制台”。它给了我这个错误。我该如何解决这个问题?我尝试更新rubygems,但它也给出了权限被拒绝的错误,我也无法做到。railsc错误:Warning:You'reusingRubygems1.8.24withSpring.UpgradetoatleastRubygems2.1.0andrun`gempristine--all`forbetterstartupperformance./opt/rh/ruby193/root/usr/share/rubygems/rubygems
我正在尝试从Postgresql表(table1)中获取数据,该表由另一个相关表(property)的字段(table2)过滤。在纯SQL中,我会这样编写查询:SELECT*FROMtable1JOINtable2USING(table2_id)WHEREtable2.propertyLIKE'query%'这工作正常:scope:my_scope,->(query){includes(:table2).where("table2.property":query)}但我真正需要的是使用LIKE运算符进行过滤,而不是严格相等。然而,这是行不通的:scope:my_scope,->(que
这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下
ruby如何管理内存。例如:如果我们在执行过程中采用C程序,则以下是内存模型。类似于这个ruby如何处理内存。C:__________________|||stack|||------------------||||------------------|||||Heap|||||__________________|||data|__________________|text|__________________Ruby:? 最佳答案 Ruby中没有“内存”这样的东西。Class#allocate分配一个对象并返回该对象。这就是程序
这似乎非常适得其反,因为太多的gem会在window上破裂。我一直在处理很多mysql和ruby-mysqlgem问题(gem本身发生段错误,一个名为UnixSocket的类显然在Windows机器上不能正常工作,等等)。我只是在浪费时间吗?我应该转向不同的脚本语言吗? 最佳答案 我在Windows上使用Ruby的经验很少,但是当我开始使用Ruby时,我是在Windows上,我的总体印象是它不是Windows原生系统。因此,在主要使用Windows多年之后,开始使用Ruby促使我切换回原来的系统Unix,这次是Linux。Rub
我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的