2011-09-21 132 views
4

我刚刚执行了一个程序,在12 MB计算机(QEMU仿真!)中分配13 MB的malloc。不仅如此,我甚至通过内存浏览并填充垃圾...Malloc分配内存超过RAM

void 
large_mem(void) 
{ 
    #define LONGMEM 13631488 
    long long *ptr = (long long *)malloc(LONGMEM); 
    long long i; 
    if(!ptr) { 
    printf("%s(): array allocation of size %lld failed.\n",__func__,LONGMEM); 
    ASSERT(0); 
    } 
    for(i = 0 ; i < LONGMEM ; i++) { 
    *(ptr+i)=i; 
    } 
    free(ptr); 
} 

这怎么可能?我期待分段错误。

+0

哇!只是意识到forloop内部的代码是错误的......仍然仍然...!为什么没有seg故障? – raj

回答

10

它被称为虚拟内存它被分配给你的程序。这不是真实你称为RAM的内存。

虚拟内存也有最大限制,但它高于内存。它由您的操作系统实施(并定义)。

+0

所以没有最大限度或什么? – raj

+0

当我继续请求操作系统时,新页面会被换入吗? – raj

+3

@raj:理论极限由指针的大小决定。实际上,大多数操作系统会比指针大小产生的任何地址空间都给你更少的内存。而且,是的,如果你分配的内存比机器中物理存在的多,你将会交换。 – sbi

4

听起来像是你的操作系统是swapping pages

分页是虚拟内存实现的最 现代通用操作系统的重要组成部分,允许他们使用 磁盘存储不符合数据进入物理随机存取存储器(RAM)。

换句话说,操作系统使用一些硬盘空间,以满足您的13 MB分配请求(在速度的巨大的代价,因为硬盘是多,比RAM慢得多)。

6

这被称为懒惰分配。

大多数Linux操作系统都有一个Lazy Allocation内存模型,其中返回的内存地址是一个虚拟地址,实际分配仅在访问时发生。操作系统假定它将能够在访问时提供此分配。

malloc分配的内存不被真实内存支持,直到程序实际触及它。

虽然calloc将内存初始化为0,但您可以确定操作系统已经用实际RAM(或交换)支持分配。

尝试使用calloc,并且很可能它会使您退出内存,除非您的交换文件/分区足够大以满足请求。

+0

哦!我碰他们!看看'for'循环.. – raj

+0

我认为他的意思是访问时间。 – raj

+0

@sbi:是的,更正了,谢谢。 –

2

除非虚拟化操作系统具有可用交换功能,否则您遇到的情况称为过量使用,它基本上存在是因为管理具有虚拟内存和需求/写入时复制页面的系统中资源的简单方法是不管理他们。过度使用就像一家银行借出的资金比实际上多 - 它似乎运作了一段时间,然后事情就崩溃了。建立一个Linux系统时,你应该做的第一件事是用命令解决此问题:

echo "2" > /proc/sys/vm/overcommit_memory 

这只是影响当前运行的内核;您可以通过添加一条线使其成为永久性的:/etc/sysctl.conf

vm.overcommit_memory=2 
相关问题