Почему стековая память оптимизирована для хранения основных компонентов, а не массивов
Что проверяют
Отличаете ли вы стек в языках с ручным управлением памятью от того, как устроена виртуальная машина Android. В самой формулировке ловушка: в Java и Kotlin массив в стек положить нельзя вообще, и сильный ответ начинается именно с этого.
Как отвечать
Сначала поправить постановку. На стеке лежат только примитивы и ссылки. Любой массив и любой объект создаётся в куче, а в кадре метода остаётся ссылка на него. Аналога массива переменной длины из C здесь нет, поэтому выбора «массив в стеке или в куче» у разработчика просто не существует.
Дальше объяснить, почему стек так устроен. Размер кадра должен быть известен до вызова: компилятор заранее раскладывает слоты под локальные переменные, и вход в метод сводится к сдвигу указателя. Примитив занимает фиксированное число слотов, ссылка тоже, а у массива размер известен только в рантайме. Кадр переменной длины сломал бы простую арифметику и сделал бы каждый вызов дороже.
Вторая причина это время жизни. Кадр умирает на выходе из метода, а массив почти всегда нужно вернуть наружу, положить в поле или отдать другому потоку. Данные, которые переживают вызов, обязаны лежать там, где ими управляет сборщик.
Полезно добавить нюанс: оптимизатор умеет анализ убегания, и для небольшого объекта, который не покидает метод, может не выделять память вовсе, разложив поля по регистрам. Это не «объект в стеке», а отсутствие объекта, и строить на этом рассуждение нельзя.
Где спотыкаются
Переносят проблему из C: «массив в стеке опасен, после возврата останется висячий указатель». В Java такой ситуации нет по построению, ссылка удерживает объект, и сборщик не тронет его, пока есть путь от корня.
Смешивают «примитив на стеке» с «примитив всегда на стеке». Поле-примитив внутри объекта лежит в куче вместе с объектом, элемент массива тем более. На стеке примитив оказывается, только когда он локальная переменная или аргумент.
Третье: делают вывод, что локальные массивы вредны. Вредна не куча, а лишние выделения в горячем месте: буфер на каждый кадр отрисовки или на каждый элемент списка. Лечится переиспользованием буфера, а не попыткой положить его в стек.