Серия Performance Programming: управление памятью (часть 1)

Разумное управление вычислительными ресурсами — важный аспект программирования. Даже в мире облачных вычислений, где ресурсы эластичны, они по-прежнему дороги.

По определению любой физический или виртуальный компонент ограниченной доступности в компьютерной системе называется вычислительным ресурсом. Сюда входят вычислительные ресурсы (ЦП), сетевые ресурсы (сокеты, пропускная способность), ресурсы памяти (ОЗУ, виртуальная память), ресурсы хранения (жесткие диски). Эти ресурсы часто совместно используются различными процессами, работающими на компьютере.

Хотя об управлении ресурсами можно обсудить много интересного, в этой статье основное внимание уделяется аспектам управления памятью, которые мы, программисты, контролируем. Управление памятью происходит на аппаратном уровне, уровне операционной системы и уровне приложений. Ответственность и, следовательно, контроль, который программист имеет при управлении памятью своей программы, различается в зависимости от языка программирования. Например, в C, где нет сборщика мусора, программист должен явно выделять и освобождать память, в то время как в Python это не требуется. Однако, независимо от используемого языка программирования, разработчики должны быть в курсе осведомлены о том, как память управляется базовой инфраструктурой для разработки действительно производительных систем.

Теперь мы посмотрим, как распределяется память в программе на C/C++. Типичное представление памяти программы C состоит из следующих разделов.

  1. Стек: эта структура данных LIFO (Last In First Out) используется для хранения всех временных переменных, объявленных в функции (push), когда функция завершает работу, все переменные, которые были помещены в стек, освобождаются ( поп). И теперь мы знаем, как бесконечная рекурсия приводит к ошибке переполнения стека!
  2. Куча . Это свободный раздел памяти, в котором программисты могут выделять память для переменных во время выполнения. Здесь нет ограничений по объему или размеру выделенной памяти. Однако программисты несут ответственность за освобождение памяти в куче, иначе это может привести к утечке памяти.
  3. BSS : этот сегмент содержит все глобальные переменные и статические переменные, которые инициализированы нулем или не имеют явной инициализации в исходном коде. Данные в этом сегменте инициализируются ядром ОС до арифметического 0 перед началом выполнения программы.
  4. Данные . Этот сегмент содержит любые глобальные или статические переменные, которые имеют предопределенное значение и могут быть изменены. Эти переменные либо не определены внутри функции, либо определены внутри функции, но с ключевым словом static. Это означает, что они должны сохранять свои значения при вызовах функций и, следовательно, не могут быть частью стека.
  5. Текст : это сегмент фиксированного размера, предназначенный только для чтения, который содержит исполняемые инструкции программы.

Теперь, когда мы знаем, как организована память в программах на C, в следующей части серии статей мы обсудим некоторые распространенные ошибки памяти и рекомендации по их предотвращению.

Подпишитесь на нас, чтобы узнать больше таких статей. Вы также можете посетить addskill.io, чтобы узнать о нас больше.

Некоторые ссылки, объясняющие, как осуществляется управление памятью в разных языках программирования — GO, Python, Java, JavaScript