C 无法分配大量虚拟内存

C 无法分配大量虚拟内存,c,ubuntu,memory-management,ubuntu-17.04,C,Ubuntu,Memory Management,Ubuntu 17.04,我了解到,当您尝试使用malloc()分配比RAM中可用的字节更多的字节时,它会分配虚拟内存。至少在Linux上是这样 我想分配大量的虚拟内存,比如说100GB。所以,我写了这样的东西: void* virtual_memory = malloc(100 gb int); 但返回的指针为空 我在64位Ubuntu虚拟机上执行此代码 我做错了什么 编辑 我试图实现的是使htop工具在VIRT列中为我的流程显示100GB 更新 我可以调用malloc一次分配2GB 50次我了解到,当您尝试使用ma

我了解到,当您尝试使用
malloc()
分配比RAM中可用的字节更多的字节时,它会分配虚拟内存。至少在Linux上是这样

我想分配大量的虚拟内存,比如说100GB。所以,我写了这样的东西:

void* virtual_memory = malloc(100 gb int);
但返回的指针为空

我在64位Ubuntu虚拟机上执行此代码

我做错了什么

编辑 我试图实现的是使
htop
工具在VIRT列中为我的流程显示100GB

更新 我可以调用malloc一次分配2GB 50次

我了解到,当您尝试使用malloc()分配比RAM中可用字节更多的字节时,它会分配虚拟内存

首先,这是不正确的。您总是分配虚拟内存。此虚拟内存映射到物理内存(RAM)或交换空间上的某个区域。如果交换空间+物理内存小于100 GBs,则分配将失败。另外,如果
libc
实现设置了一些(可编程的)限制,那么它可能无法分配如此大的数量

但是我有一个奇怪的任务,在htop工具中显示100gb的虚拟内存。据称,它可以通过一行代码实现

是的,如果您只需要这么多虚拟内存,您可以保留内存,但不能提交它。您可以阅读(*NIX)或(Windows)如何用于相同的功能

当您保留一个特定的虚拟地址范围时,您会告诉操作系统您打算使用这个范围,所以其他代码不能使用这个范围。但这并不意味着你可以真正使用它。这也意味着它不需要RAM/交换备份。因此,您将能够保留任意大的数量(当然,在64位系统上少于2^48字节)

虽然我不确定
htop
是否会将其包含在显示的值中,但您必须尝试一下

如果这确实没有增加虚拟内存数量,您可以将其映射到文件,而不是匿名映射。这可能会在您的系统上创建一个100 GB的文件(假设您有那么多空间),但您甚至应该能够读/写它

以下代码可在linux上使用-

int fd = open("temp.txt", O_RDWR | O_CREAT);
void* addr = mmap(NULL, 100 * GBS, PROT_WRITE | PROT_READ, MAP_PRIVATE, fd, 0);

以下代码为我完成了这件事:

for (int i = 0; i < 50; ++i) {
    malloc(int_pow(2, 31));
}
for(int i=0;i<50;++i){
马洛克(国际战俘(2,31)),;
}

其中,
int\u pow
只是一个自定义的
pow
实现,它操作整数。运行此应用程序后,
htop
工具显示它正好使用100GB的虚拟内存。

您的交换区有多大?可能与此相关:您的系统是否有超过100G的虚拟内存?你的报告是什么?也许你误解了虚拟内存的工作原理?除了上面的评论,什么是
gb
?我可以想象用错误的定义破坏代码的方法。实际上,似乎很难用下面的
int
来定义代码的可编译性。请注意,malloc返回的内存是连续内存。因此,不仅需要100 GB才能可用,而且还需要100 GB才能连续可用,如果在系统上无法做到这一点,那么malloc将失败。@RemyLebeau不完全如此。您需要连续的地址空间。地址空间不需要映射到连续内存。事实上,地址空间的页面可以位于不同的位置。也就是说,一些在RAM中,一些在磁盘上。是的,它总是分配虚拟内存。我错了。保留内存而不提交看起来正是我所需要的。我试试看。谢谢Linux总是保留内存而不提交。在Linux中调用
malloc
时,除非您尝试使用它,否则不会分配实际内存。如果失败,那是因为每个进程或每个系统都有一些困难的限制。以下mmap有效:mmap(0,amount,PROT_NONE,MAP_PRIVATE | MAP|u ANONYMOUS | MAP_NORESERVE,-1,0)@是的,大多数x86-64体系结构都有2^48字节的限制。这是因为64位地址行中只有48位(实际使用的是虚拟地址行和物理地址行)。其余16位应全部为0或1(基于所用位之一)。这是硬件中的一个限制,因为硬件开发人员意识到在不久的将来我们不需要整个地址范围。使用不符合此约束的任何其他地址都会导致处理器出现故障,在大多数情况下,这会向您的进程发送SIGSEGV。@SantoshKale您可以在此处阅读-