Любая последовательность Kotlin / Java команд выполняется на некотором потоке и ни для кого не секрет что каждый поток имеет свой персональный стэк, некоторую область памяти которую выделяет виртуальная машина Java.
Ниже я привёл несколько полезных фактов об этой магической штуке:
1) JVM стэк, как я уже упомянул, выделяется под каждый поток и предназначен для хранения некоторых кусков памяти называемых фреймами.
Фрейм является отдельным элементом стэка и используется для хранения локальных переменных, стэка операндов и cсылки на специальную структуру данных, содержащую информацию о текущем методе.
Возьмём для примера следующую программу:
fun main() {
println("Hello, Universe!")
}При вызове метода main будет создан фрейм, метод в таком случае называется текущим, так как на данный момент выполняется его код, затем вызывается метод println для которого будет создан новый фрейм, теперь он станет текущим и так далее, после завершения выполнения метода println его фрейм будет удалён.
2) Фреймы могут содержать стэк операндов для вычисления команд байт-кода, это как регистры процессора, чтобы вычислить что-то нужно сначала положить операнды в регистр или в случае JVM в стэк операндов.
Также фреймы используются для механизма возврата значений из метода и распространения исключений.
3) Размер стэка зависит от реализации виртуальной машины Java, для современных версий Android это около 8000-8200KB или ~8MB.
4) Если стэк переполнится JVM упадёт с исключением StackOverflowError.
5) При создании нового потока Thread можно указать в конструкторе размер стэка в битах, новый размер будет зависеть от внутренних политик JVM, например на моём телефоне удалось получить стэк размером от 2MB до 134MB.
6) Для уменьшения загрузки стэка стоит поменьше использовать рекурсию + в Kotlin были придуманы inline functions для встраивания кусков куда без вызова метода.
P.S. Хочу немного похвастаться тем, что написал первую полноценную статью!
Пишите в комментах ваше мнение и всем хорошего кода!
