为什么macOS只限制在1064或2088个进程?

在macOS中,系统的运行进程数量受限制,总数不能超过1064个(或者Catalina版本开始为2088个),而每个用户的限制是709个(或者Catalina版本为1392个)。为什么会有这样的限制?为什么限制的大小不是一个像2500这样的整数,或者一个二进制的整数,比如1024?
更新:实际上,限制的大小取决于OS X/macOS的版本和计算机中安装的内存量。在Catalina之前,1064是常见的限制值,然后变成了2088,但这些并不是Mac可能具有的唯一限制值。

7这个问题和答案解释了为什么 macOS 中进程数量的限制是 1064,而不是 1024 或者 2500。与这个问题 macOS Sierra: ulimit maxproc only 2500 不同,它并不打算回答为什么 ulimit 将每个用户的最大进程数限制为 2500,或者为什么将 ulimit 设置为 2500 实际上并不能让你运行 2500 个进程。那些答案已经附在那个问题下面了。 - Old Pro
1个回答

据我所知,答案是计算机长期历史的一部分。
macOS基于Darwin,它是苹果操作系统的核心,而Darwin本身则基于xnu,这是FreeBSD在Mach上的混合体,而Mach又是基于...直到你回溯到非常久远的时候,比如阿达·洛夫莱斯?信不信由你,这只是对macOS历史的简化,但它涵盖了理解后续内容所需的要点。
在FreeBSD开发的那个年代,内存非常昂贵,因此有强烈的动力尽量少用,但又不至于无法构建一个供大学部门共享的系统。想法是拥有一台计算机可以同时供多人使用,即使内存很贵,用户只消耗一些内存和磁盘空间,而不是整个计算机,所以你希望能够为尽可能多的人提供服务,而不损害整个系统。
内核有一个保留的内存段,用于保存每个进程的信息,该表的大小限制了系统一次可以运行的总进程数,因此您希望将该表尽可能地保持小,但同时又足够大以运行足够多的进程来为所有用户提供服务。其他内核内存保留,例如分配给临时存储网络流量的缓冲区数量,也需要随并发用户数增加而调整,因此FreeBSD引入了一个名为MAXUSERS的调优参数,它不是系统能处理的用户数量上限,而是一个你设置的指示在一次处理中所需处理的最大用户数的调优参数。它调整了内核分配的内存和可供用户使用的内存之间的平衡。
在图形用户界面出现之前,Unix系统上的个别用户通常只运行很少的进程。他们运行一个终端shell,可能会运行一个编辑器、一个电子邮件程序、一个编译器和一些其他程序,每个程序都是一个进程。电子邮件程序和编译器会运行其他一些进程。某个时候,有人估计用户可能一次只需要运行不超过16个进程。
某人(可能是同一个人)估计系统本身可以安全地限制在大约20个进程。
这为根据系统支持的并发用户数来调整进程表的大小提供了基础。
#define NPROC (20 + 16 * MAXUSERS)

在苹果将xnu整合到他们的系统中时(以及xnu从FreeBSD分叉出来的时间),MAXUSERS默认为32。有32个用户时,NPROC为532。而且在OS X 10.0中也是如此。532是系统范围内进程总数的限制。每个用户的限制是这个数量的一半:266。
直到OS X 10.7 Lion之前,情况一直如此。在那个时候,苹果添加了一个缩放因子。(实际上,在Lion之前很久就有了一个缩放因子用于服务器性能模式,但是在Lion中他们将其扩展到了普通模式。)如果您的计算机运行的是Lion或更高版本,并且具有3 GiB或更多的内存,那么maxproc会翻倍,而maxprocperuidmaxproc的一部分)会增加得更多。 maxproc从532增加到1064,maxprocperuid从266(maxproc / 2)增加到709((maxproc * 2) / 3)。
这样,您就可以获得2010年(从10.7 Lion到10.14 Mojave)的用户每个进程限制为709个,系统范围内的进程限制为1064个。
在10.10 Yosemite中,NPROC(20 + 16 * MAXUSERS)更改为(20 + 16 * 32),可能是为了摆脱MAXUSERS而保持NPROC不变。在10.15 Catlina中,NPROC首次提高,但奇怪的是他们保留了"20 +"并将其设为(20 + 32 * 32)。因此,从Catalina开始,maxproc是1044的倍数。
你问为什么是倍数?从10.13 High Sierra开始,随着内存的增加,maxproc会继续扩大。如果你有3 GiB但少于12 GiB的内存,它会翻倍,而在此之上,它会乘以内存大小除以4 GiB,直到达到一个限制,当你安装了64 GiB或更多内存时,比例因子为16。
现在你知道为什么maxproc是532或1044的倍数,而不是更常见的512或500了。
如果你想进一步提高限制,你需要切换到服务器模式。你可以在Fix “fork: resource temporarily unavailable” on OS X中了解如何做以及为什么要这样做。你还可以在What does serverperfmode=1 actually do on macOS?中详细了解服务器模式的优势。

32我喜欢你的第二段听起来非常复杂,却远远不足以涵盖 macOS 的奇怪而复杂的历史(我的意思是 OSX(我的意思是 Mac OS X(我的意思是 Rhapsody(我的意思是 OPENSTEP(我的意思是 NeXTStep)))))。 - Jörg W Mittag
6https://en.wikipedia.org/wiki/Unix#/media/File:Unix_history-simple.svg @JörgWMittag 看起来有一些步骤缺失或合并在一起了。 - anki
8@JörgWMittag 你评论的最后一部分 (我的意思是...))))) 看起来像是从某个奇怪的Lisp代码中提取出来的 :) - Aleks G
1非服务器配置的缩放因子现在实际上可以大于2,只要机器具有超过8GB的RAM(请参见此文件底部的代码:https://opensource.apple.com/source/xnu/xnu-4903.241.1/osfmk/kern/startup.c.auto.html)。拥有64GB RAM,这将产生一个maxproc值为8512 - Siguza