在Windows 32位和64位机器上,我必须分配内存来存储大量实时stream式传输的数据,总计大约1GB。 如果我使用malloc(),我将获得一个虚拟内存地址,这个地址实际上可能导致一些分页到硬盘驱动器,具体取决于我拥有的内存量。 不幸的是,恐怕HD会影响性能,导致数据丢失。
有没有办法强制内存分配只在内存中,即使这意味着我得到一个错误,当没有足够的内存可用(所以用户需要closures其他东西或使用另一台机器)? 我想保证所有的操作都将在内存中完成。 如果失败,则强制退出应用程序是可以接受的。
我知道另一个进程可能会进来,本身需要一些内存,但我并不担心,因为在这台机器没有发生(这将是唯一的应用程序在机器上做这个大的分配)。
[编辑:]我到目前为止的尝试一直是尝试使用VirtualLock,如下所示:
if(!SetProcessWorkingSetSize(this, 300000, 300008)) printf("Error Changing Working Set Size\n"); // Allocate 1GB space unsigned long sz = sizeof(unsigned char)*1000000000; unsigned char * m_buffer = (unsigned char *) malloc(sz); if(m_buffer == NULL) { printf("Memory Allocation failed\n"); } else { // Protect memory from being swapped if(!VirtualLock(m_buffer , sz)) { printf("Memory swap protection failed\n"); } }
但工作集中的更改失败,VirtualLock也是如此。 Malloc确实返回非null。
[编辑2]我也试过了:
unsigned long sz = sizeof(unsigned char)*1000000000; LPVOID lpvResult; lpvResult = VirtualAlloc(NULL,sz, MEM_PHYSICAL|MEM_RESERVE, PAGE_NOCACHE);
但lpvResult是0,所以也没有运气。
您可以使用mlock,mlockall,munlock,munlockall函数来防止页面交换(POSIX的一部分,也可在MinGW中使用)。 不幸的是,我没有使用Windows的经验,但它看起来像VirtualLock做同样的事情。
希望能帮助到你。 祝你好运!
我认为VirtualAlloc可能会让你得到一些你想要的。
这个问题真的归结为只写你自己的内存管理器,而不是使用CRT功能。
您需要使用带有锁定选项2( LOCK_VM_IN_RAM
)的未NtLockVirtualMemory
函数; 请确保您先请求并获取SE_LOCK_MEMORY_NAME
权限,并注意可能不会被授予权限(我确定组策略默认权限,但很可能授予任何人)。
我建议使用VirtualLock
作为后备,如果也失败,则使用SetProcessWorkingSetSize
。 如果失败了,就让它失败我猜…
看到这个链接关于这个一些很好的讨论。 一个人说:
指定
LOCK_VM_IN_WSL
标志时,只需告诉平衡集管理器,您不希望将某个特定的页面交换到磁盘,并在修剪目标进程的工作集时要求它离开此页面。 这只是一个指示,所以如果系统内存不足,目标页面仍然可以交换。 但是,当你指定LOCK_VM_IN_RAM
标志时,你向内存管理器发出一个指令,把这个页面当成不可分页的(即当MDL调用MmProbeAndLockPages
()来锁定页面时,做一些事情)页面问题一直保证在RAM中加载。
一种选择是从主机内存中创建一个RAM磁盘。 尽管在分布式Windows代码中不再支持这一功能,但仍然可以通过商业产品找到免费或可用的驱动程序。 例如,DRDataRam提供了一个免费的个人使用驱动程序和商业使用的商业许可产品: http : //memory.dataram.com/products-and-services/software/ramdisk
还有ImDisk虚拟驱动程序可在: http ://www.ltr-data.se/opencode.html/#ImDisk它是开源的,免费用于商业用途。 它使用Microsoft的可信证书进行数字签名。
有关Windows上的RAM驱动器的更多信息,请查看serverFault.com。
你应该看看地址窗口化扩展(AWE) 。 这听起来像匹配你的内存限制(重点是我):
AWE在32位虚拟地址空间内使用物理非分页内存和该物理内存各个部分的窗口视图。