8

在 Windows 32 位和 64 位机器上,我必须分配内存来存储大量实时流式传输的数据,总共大约 1GB。如果我使用 malloc(),我将获得一个虚拟内存地址,根据我拥有的内存量,这个地址实际上可能会导致对硬盘驱动器的一些分页。不幸的是,我担心 HD 会影响性能并导致数据丢失。

有没有办法强制内存仅在 RAM 中分配,即使这意味着当没有足够的内存可用时出现错误(因此用户需要关闭其他东西或使用另一台机器)?我想保证所有操作都在内存中完成。如果失败,强制应用程序退出是可以接受的。

我知道可能会出现另一个进程,并且它本身会占用一些内存,但我并不担心,因为在这台机器上并没有发生这种情况(它将是机器上唯一执行这种大分配的应用程序)。

[编辑:] 到目前为止,我的尝试是尝试使用 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 确实返回非空值。

[Edit2] 我也试过:

 unsigned long sz = sizeof(unsigned char)*1000000000;
 LPVOID lpvResult;
 lpvResult = VirtualAlloc(NULL,sz, MEM_PHYSICAL|MEM_RESERVE, PAGE_NOCACHE);

但是 lpvResult 是 0,所以也没有运气。

4

5 回答 5

6

您可以使用mlock、mlockall、munlock、munlockall函数来防止页面被交换(POSIX 的一部分,在 MinGW 中也可用)。不幸的是,我没有使用 Windows 的经验,但看起来VirtualLock做了同样的事情。

希望能帮助到你。祝你好运!

于 2013-01-11T20:12:12.727 回答
4

我认为VirtualAlloc可能会给你一些你想要的东西。

这个问题实际上归结为只是编写自己的内存管理器而不是使用 CRT 函数。

于 2013-01-11T20:12:44.620 回答
2

您需要将未记录的NtLockVirtualMemory功能与锁定选项 2 ( LOCK_VM_IN_RAM) 一起使用;确保您首先请求并获得SE_LOCK_MEMORY_NAME特权,并注意它可能不会被授予(我确定组策略默认的特权是什么,但它很可能被授予任何人)。

我建议使用VirtualLock作为后备,如果也失败了,使用SetProcessWorkingSetSize. 如果失败了那就让它失败吧,我猜......

有关此问题的一些很好的讨论,请参见此链接。一个人说:

当您指定LOCK_VM_IN_WSL标志时,您只需告诉平衡集管理器您不希望将某些特定页面交换到磁盘,并要求它在修剪目标进程的工作集时不理会该页面。这只是一个指示,因此如果系统内存不足,目标页面可能仍会被交换。但是,当您指定LOCK_VM_IN_RAM标志时,您会向内存管理器发出指令以将此页面视为不可分页(即驱动程序在调用MmProbeAndLockPages() 时执行某些操作以锁定页面,由 MDL 描述),以便该页面问题是保证一直加载到 RAM 中。


编辑:

这个

于 2013-01-11T21:33:18.863 回答
0

一种选择是从主机的内存中创建一个 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。

于 2013-01-11T21:44:33.183 回答
0

您应该看看Address Windowing Extensions (AWE)。听起来它与您的内存限制相匹配(强调我的):

AWE在 32 位虚拟地址空间内使用物理非分页内存和该物理内存各个部分的窗口视图。

于 2013-01-11T22:10:45.433 回答