[为什么当我尝试在每个循环中分配一个字节时,虚拟内存的数量却从未减少,如cout
的statex.ullAvailVirtual
所示?
如果将动态内存分配更改为VirtualAlloc()
,则在每个循环中我都可以看到虚拟内存的大小减少了4个字节,这是合乎逻辑的,因为页面的大小为4个字节。
#include <Windows.h>
#include <iostream>
int main()
{
unsigned int allocated = 0;
while (true)
{
MEMORYSTATUSEX statex;
statex.dwLength = sizeof(statex);
GlobalMemoryStatusEx(&statex);
//Depleting the memory per byte.
char* dyn_mem = new char[1];
*dyn_mem = 'a';
std::cout << "There are " << statex.ullAvailVirtual / 1024 << " free KB of virtual memory." << std::endl;
}
return 0;
}
您看到的是内存分配优化。有关分配和解除分配工作方式的更多详细信息,请参见this answer。基本上,从OS一次分配每个字节(或者可能根本不可能)效率很低,因为它通常处理页面中的内存(在我的系统上为4KB),而不是单个字节。
您的平台的编译器供应商(如果在这种情况下使用msvc,则为Microsoft)非常了解这一点,并以某种方式实现低级内存分配,以便他们处理子页面分配。例如,malloc
可能在应用程序启动时分配一页内存。该程序在启动时可能不需要那么多内存,因此malloc可以跟踪它从OS请求的内容以及应用程序从malloc请求的内容。如果malloc空间不足,则会从操作系统请求另一个页面。
标准库容器(如std::vector
)的工作方式非常相似(请参见std::vector::resize
和std::vector::reserve
)。
如果将每次迭代的分配增加到10个字节(而不是1个),则会看到内存变化非常快。就我而言,您可以看到过渡发生了:
There are 137434705464 free KB of virtual memory.
There are 137434705464 free KB of virtual memory.
There are 137434705464 free KB of virtual memory.
There are 137434701368 free KB of virtual memory.
There are 137434701368 free KB of virtual memory.
There are 137434701368 free KB of virtual memory.
您可以看到4096字节发生了一次更改,与我的系统上的页面大小相匹配。此时,malloc(或使用的任何分配功能)用完了保留的内存,并请求了一个新块。
请注意,我在此处将malloc
用作任何常见内存分配功能的占位符。