我需要使用 VirtualAlloc 为我的项目分配可执行内存,以便 JIT 将自定义脚本格式重新编译为 x86/etc。但我感到困惑的是,其他人似乎都没有注意到,而且它的行为似乎明显缺乏细节。
我知道它分配“虚拟”内存,这意味着它可以是物理上的任何东西(RAM/磁盘),但在使用时它可以简单地被视为“内存”。但是,例如,如果我做类似的事情:
#define MB 1024*1024
auto pAddr = VirtualAlloc(NULL, 8*MB, MEM_RESERVE, PAGE_NOACCESS);
VirtualAlloc(pAddr + 4*MB, 1*MB, MEM_COMMIT, PAGE_EXECUTE_READWRITE); // commit 1MB, 4MB's into the reserved memory
是只使用了 1MB 还是 5MB?显然,我并不期望它是 5MB - 我只是不知道在这种看似显而易见的情况下会发生什么。有效吗?保留内存中的任何范围都可以自由提交和取消提交吗?更重要的是,它可以乱序使用还是应该增量分配(根据 MSDN 文档,看起来你可以用它来做)。还是 VirtualAlloc 只对一次分配“页面”感到满意?
我发现的每个示例似乎只对向我展示如何分配页面感兴趣——这可能只是最基本的用途,但远非最实用——但我想用它来为脚本分配编译代码,这可能是偶尔在执行期间重新编译。我需要尝试为这些分配创建某种接口(interface),这样我就可以简单地说“为这个脚本编译提供一些内存”,它会自动返回以前未使用的提交空间或提交一些新空间 - 所以任何提示如何最好地从虚拟内存分配(例如,最好不要取消提交可能会再次提交的内存?)也将受到赞赏。
最佳答案
好的;我认为我明白你的意思,我希望这会澄清事情。
从概念上讲,VirtualAlloc 在单独的页面上工作。
为简单起见,让我们考虑一个 32 位 x86 进程。虚拟地址空间是从第 0 页到第 1048575 页的一系列页面。这些页面中的每一个都可能保留也可能不保留;如果保留,则可能会或可能不会提交。 (如果提交,它也将有零个或多个内存保护选项,并且页面可能处于各种其他状态,但我们现在几乎可以忽略所有这些。)
无法只保留或提交页面的一部分,或者同一页面的两个部分具有不同的内存保护选项。相反,保留和/或提交的页面是否连续并不重要。
如果您使用特定的起始地址和区域大小调用 VirtualAlloc,那么它会作用于指定虚拟地址区域中包含一个或多个字节的每一页。地址和大小仅用于计算要作用于哪些页面。参数是地址而不是页码的唯一原因是为了简化程序员的工作。
从概念上讲,一次覆盖多个页面的 VirtualAlloc 调用等同于为每个页面调用一次 VirtualAlloc。唯一的区别(效率除外)是一次对多个页面进行操作是原子的,因此在整个范围内要么失败要么成功。
请特别注意,如果您成功多次调用 VirtualAlloc 覆盖连续的页面,则无法告诉后记这些页面是单独分配的。操作系统只记得页面处于什么状态,而不是它是如何到达那里的。 [附录:糟糕;这是错误的。 VirtualQuery 的文档说它可以判断连续的页面是否属于同一分配。也许它们被标记了唯一的分配 ID 或其他东西。我不相信内存管理器实际上使用了这些信息,但显然它 被保留了。]
请记住,HeapCreate 函数已经允许您创建一个堆,其内存块允许代码执行。除非您的应用程序有非常特殊的需求,否则您不太可能通过编写自己的堆管理器获得任何好处。
关于c++ - VirtualAlloc 的困惑 - 它只适用于页面吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22183228/
大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我已经在Sinatra上创建了应用程序,它代表了一个简单的API。我想在生产和开发上进行部署。我想在部署时选择,是开发还是生产,一些方法的逻辑应该改变,这取决于部署类型。是否有任何想法,如何完成以及解决此问题的一些示例。例子:我有代码get'/api/test'doreturn"Itisdev"end但是在部署到生产环境之后我想在运行/api/test之后看到ItisPROD如何实现? 最佳答案 根据SinatraDocumentation:EnvironmentscanbesetthroughtheRACK_ENVenvironm
当我使用has_one时,它工作得很好,但在has_many上却不行。在这里您可以看到object_id不同,因为它运行了另一个SQL来再次获取它。ruby-1.9.2-p290:001>e=Employee.create(name:'rafael',active:false)ruby-1.9.2-p290:002>b=Badge.create(number:1,employee:e)ruby-1.9.2-p290:003>a=Address.create(street:"123MarketSt",city:"SanDiego",employee:e)ruby-1.9.2-p290
如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:
我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我
require'mechanize'agent=Mechanize.newlogin=agent.get('http://www.schoolnet.ch/DE/HomeDE.htm')agent.clicklogin.link_withtext:/Login/然后我得到Mechanize::UnsupportedSchemeError。 最佳答案 Mechanize不支持javascript但您可以将搜索字段添加到表单并为其分配搜索词并使用mechanize提交表单form=page.forms.firstform.add_fie
我正在使用带有Rails的Devise,我想添加一个方法“getAllComments”,所以我这样写:classUser在我的Controller中:defdashboard@user=current_user@comments=@user.getAllComments();end当我访问我的url时,我得到了undefinedmethod`getAllComments'for#我做错了什么?谢谢 最佳答案 因为getAllComments是一个类方法,而您正试图将其作为实例方法访问。您要么需要访问它:User.getAllCom
我正在使用Rails3.2.3和Ruby1.9.3p0。我发现我经常需要确定某个字符串是否出现在选项列表中。看来我可以使用Ruby数组.includemethod:或正则表达式equals-tildematchshorthand用竖线分隔选项:就性能而言,一个比另一个好吗?还有更好的方法吗? 最佳答案 总结:Array#include?包含String元素,在接受和拒绝输入时均胜出,对于您的示例只有三个可接受的值。对于要检查的更大的集合,看起来Set#include?和String元素可能会获胜。如何测试我们应该根据经验对此进行测试
我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“