Я не уверен, говорите ли вы о рекурсии или многопоточных вызовах, поэтому я предполагаю, что вы имеете в виду рекурсию.
Каждый раз, когда вы вызываете метод, все локальные переменные, которые не объявлены как статические,размещены в стеке.Это работает так, что каждый вызов имеет свой собственный «фрейм» стека. Когда вызов завершается, фрейм стека освобождается (и все локальные переменные уничтожаются).
Поэтому, когда вызывается функция foo (), этолокальные переменные находятся в кадре в стеке, давайте назовем его кадром A. Если foo вызывает себя, добавляется еще один кадр, назовем его B. В течение жизни этого второго вызова существуют оба кадра A и B, но A по существубездействующий (обычно данные в A могут быть изменены косвенно, например, с помощью указателей).Когда второй вызов завершается, B-кадр освобождается, и A-кадр снова становится активным.Наконец, когда завершается главный вызов, фрейм A исчезает.
Поскольку объем стека ограничен, вы должны быть осторожны, чтобы не создавать больше фреймов, чем может вместить стек.Если вы это сделаете, то стек называется переполнением.