C Linux上的虚拟内存大小

C Linux上的虚拟内存大小,c,linux,memory,C,Linux,Memory,我试图深入理解操作系统Linux上的虚拟内存管理 我真的不明白操作系统是如何决定进程的VM大小的 我知道32位x86操作系统最多可以提供3 GB的虚拟机地址空间。。。这总是真的吗 在我的例子中,我有大约110 MB的物理内存和32位Linux,我的主进程有大约660 MB的vm地址空间。但是,物理内存(进程的RSS)中只有50MB,所以我的物理RAM没有满。其余部分是免费的,几乎所有部分都由页面缓存使用。这似乎是一种正常的行为 如果我检查/proc/my_process_PID/smap,则有几

我试图深入理解操作系统Linux上的虚拟内存管理

我真的不明白操作系统是如何决定进程的VM大小的

我知道32位x86操作系统最多可以提供3 GB的虚拟机地址空间。。。这总是真的吗

在我的例子中,我有大约110 MB的物理内存和32位Linux,我的主进程有大约660 MB的vm地址空间。但是,物理内存(进程的RSS)中只有50MB,所以我的物理RAM没有满。其余部分是免费的,几乎所有部分都由页面缓存使用。这似乎是一种正常的行为

如果我检查/proc/my_process_PID/smap,则有几个8MB匿名VMA

我的实际问题是,我需要在代码中添加一个10 MB的malloc,但不幸的是,OOM杀手杀死了我的进程(内存不足)。。。我认为在堆的虚拟机中没有更多可用的免费页面了,不是吗?某个地方有巨大的内存泄漏吗

为什么操作系统不扩展我的进程虚拟机大小


有关vm大小的信息,请参见:ulimit-v:unlimited

每个进程可以有3GB的虚拟内存(大约,在许多32位Linux上),并继续创建占用千兆字节虚拟内存的新进程。内核的开销很小,但是虚拟内存非常便宜。您正在使用的地址空间量可能并不重要,而且它可能不会触发OOM杀手

但是,您的系统只有这么多RAM。当您开始在地址空间中使用页面(写入页面)时,内核被迫找到物理RAM来将它们映射到。如果没有物理RAM,内核可以从RAM中逐出其他页面——要么交换它们,要么丢弃它们。但是如果它不能删除任何页面,那么它就会触发OOM杀手

地址空间不足将导致
malloc
在我的系统上返回
NULL
,而不是触发OOM killer

听起来您的进程只是使用了太多的RAM。RSS不是进程使用的内存量,它只是当前物理RAM中的内存量。如果您的进程内存泄漏并持续增长,RSS最终将停止增长——因为对于您使用的每一个新页面,内核将从您的进程中逐出一个页面


尝试使用内存分析器,如Valgrind。这将帮助您理清应该担心哪些内存(mallocs)以及可以忽略哪些内存(共享库和其他内存映射文件)。内核(和/proc)不会提供足够的详细信息。

linux系统上可用的虚拟内存空间总量(大致)为
RAM
+
交换空间
-
内核开销
。RAM是您已经安装的硬件,内核开销大致是一个常数(虽然在内核版本之间有所不同),因此控制可用VM总空间的唯一简单方法是添加或删除交换空间

除了总限制之外,还有每个进程的VM限制。这是可配置的,并且(至少在32位linux上)最多为3GB,但可能会少一些
ulimit-v
将告诉您此限制或可用于更改此限制

当进程请求更多VM空间时(通常通过malloc),内核将查看所有这些限制,如果超过任何限制,将返回0。另一方面,OOM杀手只有在接近总VM限制时才会出现。然而,当OOM杀手杀死你时,你就死了——没有内存不足的错误,也没有抓住它的机会


因此,如果您真的遇到了总VM限制,并且希望避免这种情况,您可以分配更多的交换空间,或者去掉(首先杀死或不启动)其他占用大量VM空间的进程,以便为您的程序腾出一些空间。

您的问题是什么;你希望操作系统给你不存在的内存吗?这台机器是否有任何页面文件或磁盘形式的“备份存储”?我“无法”理解的是,我的操作系统为110 MB的物理内存分配了大约660 MB的虚拟内存,而现在操作系统不允许我在进程中再分配10 MB。为什么他不将虚拟机的大小扩展到670MB呢?660/110是过度使用的六倍。那很难。但请记住:还有其他过程。(试着找出哪一个;也许你可以减少)操作系统希望为新启动的进程和缓冲区保留一些空闲内存。我将使用mtrace()log检查是否存在巨大的内存泄漏。@ArnaudG:660 MB的虚拟内存不一定都太多。它包括共享内存映射,可以很容易地收回。由于内存映射,最大虚拟内存是否比RAM大很多,比如数百GB?