💡Стек или куча?



🤔 Живет ли переменная на стеке вызовов, или она динамически выделена в куче?



В большинстве случаев вам не стоит беспокоиться об этом. Go собирает мусор и автоматически очищает неиспользуемые переменные.



Однако сборка мусора имеет свою цену, поэтому чем меньше выделений делает ваш код, тем быстрее он может работать.



📌 Как узнать, выделяется ли переменная в куче?



Некоторые операции по умолчанию вызывают выделение памяти в куче и поэтому легко обнаруживаются и исправляются. Вот несколько примеров:



🔸Строковые переменные неизменяемы. Конкатенация двух строк приводит к новой аллокации и сборке мусора. В качестве альтернативы можно использовать strings.Builder.

🔸Срезы, которые растут за пределы своей емкости, реаллоцируются. Решение: предварительно выделить срез с помощью make().

🔸Когда функция создает локальную переменную и возвращает указатель на эту переменную, переменная должна быть выделена в куче.



📌 Однако есть ситуации, когда выделения в куче неочевидны. Подумайте об указателях, скрытых внутри других типов данных, таких как срезы или мапы. Или рассмотрите массивы. Если массив слишком большой, чтобы жить на стеке, он выделяется в куче.



📌 Как найти эти случаи выделения в куче?



Запустите или скомпилируйте свой код с флагом сборки мусора "-m", и команда Go выведет заметку каждый раз, когда переменная перемещается или уходит со стека в кучу:



go run -gcflags "-m" 

или

go tools compile -m





#tip