スタックの割り当てには、当然ながら多くの関連する質問があります
ただし、さまざまな* nixマシンでは、bashコマンドを発行できます。
ulimit -s unlimited
またはcshコマンド
set stacksize unlimited
これにより、プログラムの実行方法がどのように変わりますか?プログラムまたはシステムのパフォーマンスに影響はありますか(たとえば、これがデフォルトにならない理由など)?
より多くのシステムの詳細が関連する場合、x86_64ハードウェアで実行されているLinux上のGCCでコンパイルされたプログラムに最も関心があります。
関数を呼び出すと、新しい「名前空間」がスタックに割り当てられます。これが、関数がローカル変数を持つ方法です。関数が関数を呼び出すと、関数が関数を呼び出すので、この深い名前空間の階層を維持するために、スタック上でますます多くのスペースを割り当て続けます。
大量のスタックスペースを使用するプログラムを抑制するには、通常、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
コマンドを使用して、スタックの制限を削除すると、パフォーマンスが数秒の数分の1だけ向上することがわかりました(少なくとも64ビットUbuntuで)。
Mea culpa、スタックサイズcanは無制限です。 _STK_LIM
はdefaultです。_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
が定義されているものを意味し、無限の場合は無限です。無限に設定することの意味と、それが持つ可能性のある意味の詳細については、他の答えを参照してください、それは私のものよりもはるかに優れています。
「ulimit -s unlimited」は、スタックを無制限に拡張します。これにより、特にプログラムが末尾再帰ではなく(コンパイラがこれらを「最適化」できる)、再帰の深さが大きい場合、プログラムを再帰的に記述する場合にプログラムがクラッシュするのを防ぐことができます。
@seisvelasの答えには、質問に対する正しい答えがほとんど含まれています。しかし、それは多くの虚偽の主張に深く埋もれています-コメントを参照してください。したがって、私はこの答えを書く義務があると感じました。