W praktyce powiększanie stosu jest trudne (a czasem niemożliwe). Zrozumienie, dlaczego wymaga pewnego zrozumienia pamięci wirtualnej.
W Ye Olde Days aplikacji jednowątkowych i ciągłej pamięci trzy były trzema komponentami przestrzeni adresowej procesu: kodem, stertą i stosem. To, jak te trzy układano, zależało od systemu operacyjnego, ale ogólnie kod był pierwszy, poczynając od dolnej części pamięci, sterty następowały dalej i rosły w górę, a stos zaczynał się na górze pamięci i wzrastał w dół. Pewna pamięć była zarezerwowana dla systemu operacyjnego, ale możemy to zignorować. Programy w tamtych czasach miały nieco bardziej dramatyczne przepełnienia stosu: stos zawalałby się na stosie, i w zależności od tego, który zaktualizowano jako pierwszy, albo pracowałeś ze złymi danymi, albo wróciłeś z podprogramu do dowolnej części pamięci.
Zarządzanie pamięcią zmieniło nieco ten model: z perspektywy programu nadal istniały trzy komponenty mapy pamięci procesu i były one ogólnie zorganizowane w ten sam sposób, ale teraz każdy z komponentów był zarządzany jako niezależny segment, a MMU zasygnalizowałoby System operacyjny, jeśli program próbował uzyskać dostęp do pamięci poza segmentem. Gdy już dysponujesz pamięcią wirtualną, nie było potrzeby ani chęci udzielania programowi dostępu do całej jego przestrzeni adresowej. Tak więc segmentom przypisano stałe granice.
Dlaczego więc nie jest pożądane, aby dać programowi dostęp do pełnej przestrzeni adresowej? Ponieważ ta pamięć stanowi „ładunek popełnienia” przeciwko zamianie; w dowolnym momencie może być konieczne zapisanie dowolnej lub całej pamięci dla jednego programu w celu zamiany, aby zrobić miejsce dla pamięci innego programu. Jeśli każdy program może potencjalnie zużyć 2 GB swapu, musisz albo zapewnić wystarczającą ilość swapów dla wszystkich swoich programów, albo zaryzykować, że dwa programy będą potrzebowały więcej niż mogłyby.
W tym momencie, zakładając wystarczającą przestrzeń adresu wirtualnego, to mógłby rozszerzyć te segmenty, jeśli to konieczne, a segment danych (heap) ma w rzeczywistości rośnie z upływem czasu: zaczynasz z małym segmencie danych, a gdy przydzielania pamięci żąda więcej przestrzeni gdy jest to jest potrzebne. W tym momencie, przy użyciu pojedynczego stosu, fizycznie byłoby możliwe rozszerzenie segmentu stosu: system operacyjny mógłby złapać próbę wypchnięcia czegoś poza segment i dodać więcej pamięci. Ale to również nie jest szczególnie pożądane.
Wprowadź wielowątkowość. W takim przypadku każdy wątek ma niezależny segment stosu, ponownie o ustalonym rozmiarze. Ale teraz segmenty są ułożone jeden po drugim w wirtualnej przestrzeni adresowej, więc nie ma sposobu na rozwinięcie jednego segmentu bez przesunięcia drugiego - czego nie można zrobić, ponieważ program potencjalnie będzie miał wskaźniki na pamięć żyjące na stosie. Alternatywnie możesz zostawić trochę miejsca między segmentami, ale przestrzeń ta zostałaby zmarnowana w prawie wszystkich przypadkach. Lepszym rozwiązaniem było obciążenie dewelopera aplikacji: jeśli naprawdę potrzebujesz głębokich stosów, możesz to określić podczas tworzenia wątku.
Dzisiaj, dzięki 64-bitowej wirtualnej przestrzeni adresowej, moglibyśmy tworzyć efektywnie nieskończone stosy dla efektywnie nieskończonej liczby wątków. Ale znowu, nie jest to szczególnie pożądane: w prawie wszystkich przypadkach przepełnienie stosu oznacza błąd w kodzie. Zapewnienie stosu 1 GB po prostu odracza wykrycie tego błędu.