Windows如何知道我没有使用内存?

我注意到这种奇怪的效果,内存没有注册为Windows任务pipe理器分配,直到它被触摸,而不是当它是malloc -ed或new 。 在debug和优化release版本中都会出现该效果。

下面是一个结构化的例子,虽然在我的代码中,分配和使用发生在不同的线程上,所以我不认为它是优化器,尽pipe我不知道如何检查。

 for (int i = 0 ;i < 1000;i++) { buffer[i]=malloc(buffersize); } _sleep(1000*60) for (int i=0;i<1000;i++) { memset(buffer[i],0,buffersize);//Only shows up the in the resource manager here } 

我的问题是Windows如何知道我已经使用了内存? 是第一次使用监视内存还是一些编译时优化?

我的好奇心是受到我写的实时采集的动机,需要我两次触摸内存 – >分配一次,实际填充数据一次。 因此,按下一个button(“aquire!”)需要我一次写入64千兆字节的RAM,而不是一段时间,增加相当实际的延迟量。 如果我malloc我去这添加了太多的延迟。

– 编辑 –

我也禁用了Windows页面文件…

分配给您的进程的虚拟地址空间不一定由物理RAM支持。 一个例子是分页文件,其中正在使用的内存可能会移动到物理内存不足的情况下。 但是,如果你甚至从来没有写过任何物理内存或磁盘空间,那么就没有必要。 因此,作为一个优化,一些操作系统给你虚拟地址空间,而没有实际分配空间。 在某些情况下,这是非常有益的。 在其他情况下,像你一样,这有点烦人。

也就是说,任务管理器是一个非常简单的调查内存使用情况的工具。 你可以观察到这是一个幸运的巧合,许多问题不能(可靠地)只使用任务管理器来观察。

至于如何避免懒惰的分配,而不触及所有的内存…我不知道任何方式。 甚至连VirtualAlloc没有办法解决这个问题。 您可以通过每页只写一个字节来降低成本,这应该仍然会导致物理RAM分配。 但请记住,即使您可以避免编写任何内容 ,Windows仍然需要分配1600万个页面,包括页表条目。 这肯定需要一些时间。 你可以使用大页面(使用VirtualAlloc ),这使得页面几百倍,从而将上述1600万页减少到更合理的数字。

这是像Windows这样的需求页面虚拟内存操作系统的标准行为。 malloc()调用只分配虚拟内存地址空间。 在访问内存之前,您实际上并没有开始使用内存。 这会生成页面错误,迫使操作系统将您访问的内存页映射到RAM中。

这通常是一个软页面错误,通过从空闲列表中抓取一个RAM页面并将其映射,非常快速地处理这个错误。 与硬页面错误相反,当一些RAM页面被换出到交换文件时,稍后会遇到一个错误,因为另一个进程需要RAM。 从磁盘重新加载页面需要更多的时间。

禁用页面文件有助于避免这些硬页面错误。 它并没有消除它们,你的代码页也可能被换出。 当你迫使操作系统回退给他们时,可能会发生这种情况,因为它不能再换出到分页文件。 这样的页面在被换出时只是被丢弃,当页面错误返回时从可执行文件重新加载。

如果你有软实时需求,那么最好的策略是尽早分配内存并在开始承诺快速响应之前有意访问它。 可以简单地用calloc()而不是malloc()来完成。

这似乎是你的操作系统是懒惰地分配内存。 看到这个问题的答案

基本上,当你调用malloc的时候,操作系统给你的程序一个地址,并且承诺要求的内存空间可用。 我读过的类比是操作系统为内存写入一个“检查”,但是只有当程序试图通过使用它来“兑现”支票时才分配物理内存。

我想如果你想在malloc时候出现延迟命中,你应该在那里memset

您可以尝试malloc并立即为其分配一个空值来克服NicholasM正在讨论的“懒惰内存分配”。 即使如此,编译器可能会发现您正在分配但不使用分配并将其从编译的代码中移除。 但不要忘记为什么操作系统懒散地分配内存。