为什么在现代Linux上,默认堆栈大小如此之大-8MB(在某些发行版中甚至为10MB)


10

例如,在OSX上,它甚至不到512k。

有没有建议的大小,请记住,该应用程序不使用递归并且不分配很多堆栈变量
我知道这个问题太广泛了,它很大程度上取决于用法,但是我仍然想问,因为我想知道这背后是否存在一些隐藏的/内部的/系统的原因


我想知道,因为我打算在我的应用程序中将堆栈大小更改为512 KiB-听起来仍然很大,但它比8MiB小得多-并会导致进程的虚拟内存显着减少,因为我有很多线程(I / O)。

我也知道这并没有真正的伤害,请在此处进行详细说明pthreads的默认堆栈大小


您使用的是32位CPU吗?X86_64 CPU提供了高达128 TB的虚拟地址空间(在用户空间中),足以容纳8 MB的堆栈。
约翰·迈伦(JohanMyréen)

@JohanMyréen-不,x64。这没什么大不了的,我只是想知道,目前没有真正的理由这样做。
基里尔·基洛夫'18

在2019和8 MiB中有很多内存吗?我不这么认为。具有较大的默认堆栈大小使得使用递归编写程序非常容易。我很惊讶地知道Windows上的默认堆栈大小仅为1MiB!
oldherl

Answers:


15

正如其他人所说的那样,就像您在问题中提供的链接中所提到的那样,拥有8MiB堆栈不会造成任何伤害(除了占用地址空间外,在64位系统上这无关紧要)。

Linux使用8MiB堆栈已经很长时间了。该更改是在1995年7月的内核1.3.7版中引入的。当时,它被引入为引入限制,以前没有一个限制:

将堆栈限制为一些合理的默认值:如果需要,root总是可以增加此限制。8MB似乎是合理的。

在Linux上,堆栈限制还影响程序参数和环境的大小,它们限制为堆栈限制的四分之一。内核对参数和环境至少执行了32页。

对于线程,如果堆栈限制(RLIMIT_STACK)没有限制,则将pthread_create其限制应用于新线程的堆栈-在大多数体系结构上,该限制小于8MiB。


1
哇有趣。我认为这是最近引入的。我大约有200个线程(这是另一个漫长的话题,所以暂时暂时忽略它)并top显示可怕的VIRT结果。尽管进行了更深入的研究,但此虚拟地址空间的大部分是从每个线程(内存)舞台获取的,而不是堆栈大小的,因此降低堆栈大小不会显着减少虚拟内存。我只是很好奇为什么8MiB以及为什么那么多。
基里尔·基洛夫'18

“ 8 MB”仅表示如果线程决定使用它,则每个线程的堆栈可以增长到8 MB。但是物理内存只有在实际使用之前才​​会分配。如果200个线程各自使用512 KB,则将使用100 MB物理内存,而不是1.6 GB。
Guntram Blohm

如果不进行交换,则RES列中的top“此进程实际使用的内存”比VIRT更好。
kbolino '18 -10-5

1
OP的@Guntram非常清楚这一点,请参阅问题中的链接。
斯蒂芬·基特

1

堆栈的虚拟大小为8MB 。当您的应用程序尝试使用比当前物理分配更多的堆栈时,将发生页面错误。然后,内核的页面错误处理程序将分配一个物理页面,然后您的应用程序将继续。

有关完整的说明,请参见https://unix.stackexchange.com/a/280865/21212

因此,减少您的堆栈大小在减少应用程序的物理内存使用没有任何影响。


1
我已经在我的问题中链接了此答案。我还写道,我知道这一点,但这实际上并不能回答问题。还是谢谢你
Kiril Kirov '18

我认为您需要重新考虑问题的前提,这个(非)答案指出了原因。虚拟内存不是真实内存。堆栈大小可能为800MB,并且不会影响实际的内存使用,除非您的应用程序创建了价值超过8MB的堆栈帧。
kbolino '18 -10-5
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.