Linux上的虚拟内存大小

时间:2011-09-28 11:10:37

标签: c linux memory

我试图深入理解OS Linux上的虚拟内存管理。

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

我知道32位x86操作系统可以提供高达3 GB的vm地址空间......总是这样吗?

在我的情况下,我有大约110 MB物理内存和32位Linux,我的主进程有一个约660 MB的虚拟机地址空间。但是,物理内存中只有50 MB(我的进程的RSS),因此我的物理内存不足。其余的是免费的,几乎整个页面缓存使用。这似乎是一种正常行为。

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

我的实际问题是我需要在代码中创建一个额外的10 MB malloc,但不幸的是OOM-Killer杀死了我的进程(内存不足)...我认为没有更多的免费可用页面了vm为堆,不是吗?某处是否有巨大的内存泄漏?

为什么操作系统不会扩展我的进程vm大小?

有关vm大小无限制的信息:ulimit -v:unlimited

2 个答案:

答案 0 :(得分:8)

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

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

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

听起来你的过程只是使用了太多的RAM。 RSS不是您的进程使用的内存量,而只是物理RAM 中现在的数量。如果您的进程有内存泄漏并且不断增长,RSS最终会停止增长 - 因为对于您使用的每个新页面,内核将从您的进程中逐出一页。

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

答案 1 :(得分:1)

Linux系统上可用的虚拟内存空间总量(大致)RAM + swap space - kernel overhead。 RAM是您安装的硬件,内核开销大致是一个常数(尽管内核版本不同),因此控制可用VM总空间的唯一简便方法是添加或删除交换空间。

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

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

因此,如果您确实遇到了VM的总限制,并希望避免这种情况,您可以分配更多的交换空间,或者除了(首先杀死或不启动)其他正在使用的进程VM空间,以便为您的程序释放一些空间。