Я не могу говорить за "основные языки". Многие «второстепенные» языки делают записи активации, выделенные кучей, при каждом вызове используется кусок пространства кучи вместо фрагмента линейного стека. Это позволяет рекурсии идти настолько глубоко, насколько у вас есть адресное пространство для выделения.
Некоторые люди здесь утверждают, что рекурсия, такая глубокая, неправильна, и что использование «большого линейного стека» - это просто замечательно. Это не правильно. Я согласен, что если вам придется использовать все адресное пространство, у вас возникнет какая-то проблема. Однако, когда у вас очень большой граф или древовидная структура, вы хотите разрешить глубокую рекурсию и не хотите угадывать, сколько линейного стекового пространства вам нужно в первую очередь, потому что вы догадаетесь неправильно.
Если вы решили пойти параллельно, и у вас есть много (от тысячи до миллиона «зерен» [подумайте, небольшие потоки]), вы не можете выделить 10 МБ стекового пространства для каждого потока, потому что вы будете тратить гигабайты оперативной памяти Как ты вообще мог иметь миллион зерен? Легко: много зерна, которые сцепляются друг с другом; когда зерно заморожено в ожидании блокировки, вы не можете избавиться от него, и все же вы хотите запустить другие зерна, чтобы использовать имеющиеся у вас процессоры. Это максимизирует объем доступной работы и, таким образом, позволяет эффективно использовать многие физические процессоры.
Язык параллельного программирования PARLANSE использует эту модель очень большого числа параллельных зерен и распределение кучи при вызове функций. Мы разработали PARLANSE для обеспечения символического анализа и преобразования очень больших исходных компьютерных программ (скажем, нескольких миллионов строк кода). Они создают ... гигантские абстрактные синтаксические деревья, гигантские графы управления / потоков данных, гигантские таблицы символов с десятками миллионов узлов. Много возможностей для параллельных работников.
Распределение кучи позволяет лексически ограничивать программы PARLANSE даже через границы параллелизма, потому что можно реализовать «стек» в виде стека кактусов, где вилки появляются в «стеке» для субзерен, и каждое зерно может видеть записи активации (родительские области) своих абонентов. Это делает передачу больших структур данных дешевыми при повторении; вы просто ссылаетесь на них лексически.
Можно подумать, что выделение кучи замедляет программу. Оно делает; PARLANSE платит около 5% штрафа за производительность, но получает возможность обрабатывать очень большие структуры параллельно с таким количеством зерен, которое может вместить адресное пространство.