“ulimit -s unlimited”起什么作用?
- 2024-11-12 08:36:00
- admin 原创
- 19
问题描述:
可以理解的是,关于堆栈分配有很多相关问题
栈和堆是什么?在哪里?
为什么堆栈大小有限制?
栈和堆内存的大小
但是在各种 *nix 机器上我可以发出 bash 命令
ulimit -s unlimited
或 csh 命令
set stacksize unlimited
这会如何改变程序的执行方式?对程序或系统性能有影响吗(例如,为什么这不是默认设置)?
如果涉及更多系统细节,我主要关注在 x86_64 硬件上运行的 Linux 上使用 GCC 编译的程序。
解决方案 1:
当你调用一个函数时,堆栈上会分配一个新的“命名空间”。这就是函数可以拥有局部变量的原因。随着函数调用函数,而函数又调用函数,我们不断在堆栈上分配越来越多的空间来维护这种深层次的命名空间。
为了限制程序使用大量堆栈空间,通常会通过 进行限制ulimit -s
。如果我们通过 取消该限制ulimit -s unlimited
,我们的程序将能够继续吞噬 RAM 以容纳不断增长的堆栈,直到系统最终完全耗尽内存。
int eat_stack_space(void) { return eat_stack_space(); }
// If we compile this with no optimization and run it, our computer could crash.
通常,使用大量堆栈空间是意外的,或者是深度递归的征兆,可能不应该过多地依赖堆栈。因此堆栈有限制。
对性能的影响很小,但确实存在。使用该time
命令,我发现消除堆栈限制可将性能提高几分之一秒(至少在 64 位 Ubuntu 上)。
解决方案 2:
ulimit -s unlimited
让堆栈无限增长。
如果您通过递归编写程序,这可能会防止程序崩溃,特别是当您的程序不是尾递归(编译器可以“优化”它们)并且递归深度很大时。
解决方案 3:
堆栈大小确实可以是无限的。_STK_LIM
是默认值,_STK_LIM_MAX
每个体系结构都有所不同,如下所示include/asm-generic/resource.h
:
/*
* RLIMIT_STACK default maximum - some architectures override it:
*/
#ifndef _STK_LIM_MAX
# define _STK_LIM_MAX RLIM_INFINITY
#endif
从该示例可以看出,泛型值是无限的,其中RLIM_INFINITY
,在泛型情况下再次定义为:
/*
* SuS says limits have to be unsigned.
* Which makes a ton more sense anyway.
*
* Some architectures override this (for compatibility reasons):
*/
#ifndef RLIM_INFINITY
# define RLIM_INFINITY (~0UL)
#endif
因此,我猜真正的答案是 - 堆栈大小可以受某些架构限制,那么无限堆栈跟踪将意味着_STK_LIM_MAX
定义的任何东西,如果它是无穷大 - 它就是无限的。有关将其设置为无限的含义以及可能产生的影响的详细信息,请参阅另一个答案,它比我的好得多。
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理必备:盘点2024年13款好用的项目管理软件