x64 Linux中的单个进程是否有内存限制?
我们正在运行一台带有32Gb RAM的Linux服务器,我想知道我是否可以为单个进程分配大部分内存而我需要大量内存!
答案 0 :(得分:4)
某些内核有不同的限制,但在任何现代的64位Linux上,单进程限制仍远超过32GB(假设该进程是64位可执行文件)。各种发行版也可能使用sysctl
设置了每个进程限制,因此您需要检查本地环境以确保没有设置任意低限制(同时检查RPM上的ipcs -l
- 基于系统)。
AMD64端口的Debian port documentation特别提到每进程虚拟地址空间限制为128TiB(物理内存限制的两倍),因此应该是您正在使用的合理上限。
答案 1 :(得分:3)
使用setrlimit系统调用设置资源限制。您可以使用内置shell更改它们(例如,使用bsh ulimit
,limit
使用zsh进行更改。
实际限制还与RAM大小和交换大小有关。 free
命令显示这些。 (有些系统过度使用内存,但存在风险)。
进程实际上不使用RAM,它使用virtual memory之类的系统调用来消耗mmap(可能会被malloc
调用)。您甚至可以通过该调用将文件的一部分映射到内存中。
要了解进程1234的内存映射,请查看/proc/1234/maps
文件。从您自己的应用程序中,阅读/proc/self/maps
。你还有/proc/1234/smaps
和/proc/self/smaps
。尝试使用命令cat /proc/self/maps
来了解运行cat
的进程的内存映射。
在32Gb RAM机器上,通常可以运行具有31 Gb进程空间的进程(假设不存在其他大进程)。如果你还有64Gb的交换,你可以运行一个至少64Gb的进程,但这将是令人难以置信的缓慢(大部分时间将用于交换到磁盘)。您可以添加交换空间(例如,通过交换到文件,使用dd
然后mkswap
初始化,并使用swapon
激活)。
如果对服务器进行编码,请务必小心memory leaks。 valgrind
工具有助于捕获此类错误。您可以考虑使用Boehm's garbage collector
答案 2 :(得分:3)
目前的64位Linux内核限制为64TB的物理RAM和128TB的虚拟内存(请参阅RHEL limits和Debian port)。当前的x86_64 CPU(即我们在PC中拥有的)具有(虚拟)地址限制2 ^ 48 = 256TB,因为CPU中的地址寄存器如何使用所有位(高位用于页面标志,如ReadOnly,Writable,在pagetable中的ExecuteDisable,PagedToDisc等,但规范允许切换到真正的64位地址模式,达到最大值2 ^ 64 = 16EB(Exa字节)。但是,主板和CPU芯片没有这么多引脚通过地址总线将所有48位存储器地址传送到RAM芯片,因此物理RAM的限制较低(取决于制造商),但虚拟地址空间本质上可以达到超过主板上可能具有的RAM量,直到上面提到的虚拟内存限制。
每个进程的限制是通过如何设置进程的内存虚拟地址空间来提高的,因为堆栈,mmap()区域(和动态库)可能有各种大小,程序代码本身也是内核映射的进入流程空间。其中一些设置可以通过将参数传递给链接器来改变,有时可以通过源代码中的特殊指令,或者通过直接修改二进制文件(二进制具有ELF格式)来更改。机器(root)的管理员或用户也有限制(参见命令“ulimit -a”的输出)。这些限制可能是软的或硬的,用户无法克服硬限制。
此外,Linux内核可以设置为允许内存过量分配。在这种情况下,允许程序分配大量的RAM,然后只使用少量页面(参见稀疏数组,稀疏矩阵),参见Linux kernel documentation。因此,在这种情况下,程序只有在按数据填充请求的内存后才会失败,但在内存分配时则不会。