Dalam prakteknya, sulit (dan kadang-kadang tidak mungkin) untuk menumbuhkan tumpukan. Untuk memahami mengapa diperlukan beberapa pemahaman tentang memori virtual.
Dalam Ye Olde Days aplikasi single-threaded dan memori yang berdekatan, tiga adalah tiga komponen ruang alamat proses: kode, heap, dan stack. Bagaimana ketiganya diletakkan tergantung pada OS, tetapi umumnya kodenya lebih dulu, mulai dari dasar memori, tumpukan berikutnya dan tumbuh ke atas, dan tumpukan mulai di atas memori dan tumbuh ke bawah. Ada juga beberapa memori yang disediakan untuk sistem operasi, tetapi kita dapat mengabaikannya. Program pada masa itu memiliki stack overflow yang lebih dramatis: stack akan menabrak tumpukan, dan tergantung pada yang diperbarui terlebih dahulu Anda akan bekerja dengan data yang buruk atau kembali dari subrutin ke bagian memori yang sewenang-wenang.
Manajemen memori mengubah model ini agak: dari perspektif program Anda masih memiliki tiga komponen dari peta memori proses, dan mereka umumnya diatur dengan cara yang sama, tetapi sekarang masing-masing komponen dikelola sebagai segmen independen dan MMU akan memberi sinyal kepada OS jika program mencoba mengakses memori di luar segmen. Setelah Anda memiliki memori virtual, tidak ada kebutuhan atau keinginan untuk memberikan akses program ke seluruh ruang alamatnya. Jadi ruas-ruas itu diberi batas tetap.
Jadi mengapa tidak diinginkan untuk memberikan akses program ke ruang alamat lengkapnya? Karena memori itu merupakan "biaya komit" terhadap swap; kapan saja setiap atau semua memori untuk satu program mungkin harus ditulis untuk ditukar untuk memberikan ruang bagi memori program lain. Jika setiap program berpotensi mengkonsumsi 2GB swap, maka Anda harus menyediakan swap yang cukup untuk semua program Anda atau mengambil kesempatan bahwa dua program akan membutuhkan lebih banyak daripada yang bisa mereka dapatkan.
Pada titik ini, dengan asumsi ruang alamat virtual yang cukup, Anda dapat memperluas segmen ini jika diperlukan, dan segmen data (heap) sebenarnya tumbuh dari waktu ke waktu: Anda mulai dengan segmen data kecil, dan ketika pengalokasi memori meminta lebih banyak ruang saat itu dibutuhkan. Pada titik ini, dengan satu tumpukan, secara fisik dimungkinkan untuk memperluas segmen tumpukan: OS dapat menjebak upaya untuk mendorong sesuatu di luar segmen dan menambah lebih banyak memori. Tapi ini juga tidak diinginkan.
Masukkan multi-threading. Dalam hal ini, setiap utas memiliki segmen tumpukan independen, yang lagi-lagi berukuran tetap. Tapi sekarang segmen diletakkan satu demi satu di ruang alamat virtual, jadi tidak ada cara untuk memperluas satu segmen tanpa memindahkan yang lain - yang tidak bisa Anda lakukan karena program ini berpotensi memiliki pointer ke memori yang tinggal di stack. Anda juga dapat meninggalkan beberapa ruang di antara segmen, tetapi ruang itu akan terbuang dalam hampir semua kasus. Pendekatan yang lebih baik adalah dengan membebani pengembang aplikasi: jika Anda benar-benar membutuhkan tumpukan dalam, Anda bisa menentukannya saat membuat utas.
Hari ini, dengan ruang alamat virtual 64-bit, kita dapat membuat tumpukan efektif tak terbatas untuk jumlah utas yang tak terbatas secara efektif. Tetapi sekali lagi, itu tidak terlalu diinginkan: dalam hampir semua kasus, stack overlow mengindikasikan bug dengan kode Anda. Memberikan Anda tumpukan 1 GB hanya menentang penemuan bug itu.